package com.vca.service.service.Impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.vca.common.constants.Constants;
import com.vca.common.constants.NotifyConstants;
import com.vca.common.constants.OrderRedisConstans;
import com.vca.common.constants.TaskConstants;
import com.vca.common.exception.VcaException;
import com.vca.common.model.course.Course;
import com.vca.common.model.course.CourseScheduling;
import com.vca.common.model.exhibition.ExhibitionScheduling;
import com.vca.common.model.express.Express;
import com.vca.common.model.order.StoreOrder;
import com.vca.common.model.order.StoreOrderInfo;
import com.vca.common.model.sf.*;
import com.vca.common.model.sms.SmsTemplate;
import com.vca.common.model.system.SystemConfig;
import com.vca.common.model.system.SystemGroupData;
import com.vca.common.model.system.SystemNotification;
import com.vca.common.model.talk.TalkScheduling;
import com.vca.common.model.user.User;
import com.vca.common.model.user.UserCard;
import com.vca.common.model.user.UserToken;
import com.vca.common.model.vca_product.VcaProduct;
import com.vca.common.model.vca_product.VcaProductAttrValue;
import com.vca.common.page.CommonPage;
import com.vca.common.request.*;
import com.vca.common.response.*;
import com.vca.common.response.sf.ExpressResponse;
import com.vca.common.response.sf.PrintFile;
import com.vca.common.response.sf.ResponseCancel;
import com.vca.common.response.sf.SendResponse;
import com.vca.common.result.CommonResult;
import com.vca.common.utils.DateUtil;
import com.vca.common.utils.RedisUtil;
import com.vca.common.utils.VcaUtil;
import com.vca.common.vo.*;
import com.vca.service.dao.order.StoreOrderDao;
import com.vca.service.delete.OrderUtils;
import com.vca.service.service.*;
import com.vca.service.util.SFUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * StoreOrderServiceImpl 接口实现
 */
@Service
public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderDao, StoreOrder> implements StoreOrderService {

    @Value("${vca.proxy.disable}")
    private Boolean disable;

    private static final Logger logger = LoggerFactory.getLogger(StoreOrderServiceImpl.class);

    @Resource
    private StoreOrderDao dao;

    @Autowired
    private SystemStoreService systemStoreService;

    @Autowired
    private StoreOrderInfoService StoreOrderInfoService;

    @Autowired
    private UserService userService;

    @Autowired
    private UserBillService userBillService;

    @Autowired
    private StoreOrderStatusService storeOrderStatusService;

    @Autowired
    private StoreOrderRefundService storeOrderRefundService;

    @Autowired
    private ExpressService expressService;

    @Autowired
    private TemplateMessageService templateMessageService;

    @Autowired
    private LogisticService logisticService;

    @Autowired
    private OrderUtils orderUtils;

    @Autowired
    private SystemAdminService systemAdminService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private CourseService courseService;

    @Autowired
    private CourseSchedulingService courseSchedulingService;

    @Autowired
    private SystemGroupDataService systemGroupDataService;

    @Autowired
    private SFService sfService;

    @Autowired
    private TalkService talkService;

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private OnePassService onePassService;

    @Autowired
    private UserTokenService userTokenService;

    @Autowired
    private SmsService smsService;

    @Autowired
    private StoreOrderInfoService storeOrderInfoService;

    @Autowired
    private StoreOrderService storeOrderService;

    @Autowired
    private SFUtil sfUtil;

    @Autowired
    private UserCardService userCardService;


    @Autowired
    private SystemNotificationService systemNotificationService;

    @Autowired
    private SmsTemplateService smsTemplateService;

    @Autowired
    private UmsPayService umsPayService;

    @Autowired
    private VcaProductService vcaProductService;

    @Autowired
    private StoreOrderTaskService storeOrderTaskService;

    @Autowired
    private TalkSchedulingService talkSchedulingService;

    @Autowired
    private ExhibitionSchedulingService exhibitionSchedulingService;

    @Autowired
    private VcaProductAttrValueService vcaProductAttrValueService;


    /**
     * 列表
     *
     * @param request          请求参数
     * @param pageParamRequest 分页类参数
     * @return CommonPage<StoreOrderDetailResponse>
     */
    @Override
    public CommonPage<StoreOrderDetailResponse> getAdminList(StoreOrderSearchRequest request, PageParamRequest pageParamRequest) {
        QueryWrapper<StoreOrder> queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(request.getOrderNo())) {
            queryWrapper.like("order_id", request.getOrderNo());
        }
//        if (request.getStatus().equals(Constants.ORDER_STATUS_REFUNDING)) {
//            List<StoreOrderInfo> storeOrderInfos = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().in(StoreOrderInfo::getRefundStatus, 1, 3));
//            List<String> orderNos = storeOrderInfos.stream().map(StoreOrderInfo::getOrderNo).distinct().collect(Collectors.toList());
//            if (CollUtil.isNotEmpty(orderNos)) {
//                queryWrapper.in("order_id", orderNos);
//            } else {
//                getStatusWhere(queryWrapper, request.getStatus());
//            }
//        } else if (request.getStatus().equals(Constants.ORDER_STATUS_REFUNDED)) {
//            List<StoreOrderInfo> storeOrderInfos = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getRefundStatus, 2));
//            List<String> orderNos = storeOrderInfos.stream().map(StoreOrderInfo::getOrderNo).distinct().collect(Collectors.toList());
//            if (CollUtil.isNotEmpty(orderNos)) {
//                queryWrapper.in("order_id", orderNos);
//            } else {
//                getStatusWhere(queryWrapper, request.getStatus());
//            }
//        } else {
//            getStatusWhere(queryWrapper, request.getStatus());
//        }
        getStatusWhere(queryWrapper, request.getStatus());
        getRequestTimeWhere(queryWrapper, request);

        if (request.getType().equals(5)) {
            queryWrapper.between("type", 0, 4);
        } else {
            queryWrapper.eq("type", request.getType());
        }

        List<StoreOrderDetailResponse> detailResponseList = new ArrayList<>();
        //若商品名称 和 预订单手机号不为空，则先查找详情，再找到主表id
        if (StrUtil.isNotBlank(request.getProductName()) || StrUtil.isNotBlank(request.getLecturerPhone()) || StrUtil.isNotBlank(request.getSchedulingDate())) {
            String productName = request.getProductName();
            String lecturerPhone = request.getLecturerPhone();
            String schedulingDate = request.getSchedulingDate();

            QueryWrapper<StoreOrderInfo> infoQueryWrapper = new QueryWrapper<>();
            infoQueryWrapper.like(StrUtil.isNotBlank(productName), "name", productName);
            if (StrUtil.isNotBlank(request.getLecturerPhone())) {
                infoQueryWrapper.and(wrapper -> wrapper.like("lecturer_phone", lecturerPhone).or().like("lecturer_name", lecturerPhone));
            }
            if (StringUtils.isNotBlank(schedulingDate)) {
                String[] split = schedulingDate.split(",");
                String sDate = split[0];
                String eDate = split[1];
                infoQueryWrapper.between("scheduling_date", sDate, eDate);
            }
            List<StoreOrderInfo> infoList = StoreOrderInfoService.list(infoQueryWrapper);
            if (CollectionUtil.isNotEmpty(infoList)) {
                queryWrapper.in("order_id", infoList.stream().map(StoreOrderInfo::getOrderNo).collect(Collectors.toList()));
            } else {
                //说明不存在，返回空
                return CommonPage.restPage(CommonPage.copyPageInfo(PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit()), detailResponseList));
            }
        }
        //用户，手机，邮箱模糊查询
        if (StrUtil.isNotBlank(request.getRealName())) {
            String realName = request.getRealName();
            QueryWrapper<User> userQueryWrapper = new QueryWrapper<User>();
            userQueryWrapper.like("nickname", realName).or().like("phone", realName).or().like("email", realName);
            List<User> userList = userService.list(userQueryWrapper);
            if (CollectionUtil.isNotEmpty(userList)) {
                queryWrapper.in("uid", userList.stream().map(User::getUid).collect(Collectors.toList()));
            } else {
                //说明不存在，返回空
                return CommonPage.restPage(CommonPage.copyPageInfo(PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit()), detailResponseList));
            }
        }

        queryWrapper.orderByDesc("id");
        Page<Object> startPage = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<StoreOrder> orderList = dao.selectList(queryWrapper);
        if (CollUtil.isNotEmpty(orderList)) {
            detailResponseList = formatOrder1(orderList);
        }
        PageInfo<StoreOrderDetailResponse> ccpi = CommonPage.copyPageInfo(startPage, detailResponseList);
        CommonPage<StoreOrderDetailResponse> ret = CommonPage.restPage(ccpi);
        return ret;
    }


    /**
     * H5订单列表
     *
     * @param uid              用户uid
     * @param type             订单类型:1-课程/讲座/展览  2=礼品卡/纪念品/出版物
     * @param pageParamRequest 分页参数
     * @return 订单结果列表
     */
    @Override
    public List<StoreOrder> getUserOrderList(Integer uid, Integer type, PageParamRequest pageParamRequest) {
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        LambdaQueryWrapper<StoreOrder> lqw = new LambdaQueryWrapper<>();

        if (type.equals(1)) {
            lqw.in(StoreOrder::getType, 0, 1, 2, 3);
        } else if (type.equals(2)) {
            lqw.eq(StoreOrder::getType, 4);
        }
        lqw.eq(StoreOrder::getUid, uid);
        lqw.eq(StoreOrder::getUserType, 0);
        lqw.orderByDesc(StoreOrder::getId);
        return dao.selectList(lqw);
    }

    /**
     * 创建订单
     *
     * @param storeOrder 订单参数
     * @return 结果标识
     */
    @Override
    public boolean create(StoreOrder storeOrder) {
        return dao.insert(storeOrder) > 0;
    }

    /**
     * 订单基本查询一条
     *
     * @param storeOrder 参数
     * @return 查询结果
     */
    @Override
    public StoreOrder getByEntityOne(StoreOrder storeOrder) {
        LambdaQueryWrapper<StoreOrder> lqw = new LambdaQueryWrapper<>();
        lqw.setEntity(storeOrder);
        return dao.selectOne(lqw);
    }

    /**
     * 屏蔽手机关键区号
     *
     * @param mobile
     * @return
     */
    public String shieldMobileKeyword(String mobile) {
        if (mobile == null || mobile.length() < 7) {
            return mobile;
        }
        return mobile.substring(0, 3) + "****" + mobile.substring(7);

    }

    /**
     * 格式化订单信息，对外输出一致
     *
     * @param orderList List<StoreOrder> 订单列表
     * @return List<StoreOrderItemResponse>
     */
    private List<StoreOrderDetailResponse> formatOrder1(List<StoreOrder> orderList) {
        List<StoreOrderDetailResponse> detailResponseList = new ArrayList<>();
        if (CollUtil.isEmpty(orderList)) {
            return detailResponseList;
        }

        //订单id集合
        List<String> orderIdList = orderList.stream().map(StoreOrder::getOrderId).distinct().collect(Collectors.toList());

        //获取订单详情map
//        HashMap<Integer, List<StoreOrderInfoOldVo>> orderInfoList = StoreOrderInfoService.getMapInId(orderIdList);
        Map<String, List<StoreOrderInfo>> map = StoreOrderInfoService.getMapInIds(orderIdList);
        for (StoreOrder storeOrder : orderList) {
            StoreOrderDetailResponse storeOrderItemResponse = new StoreOrderDetailResponse();
            BeanUtils.copyProperties(storeOrder, storeOrderItemResponse);
            List<PreOrderCommonVo.PreOrderProductDetail> preOrderProductDetail = new ArrayList<>();
            if (ObjectUtil.isNull(map.get(storeOrderItemResponse.getOrderId()))) {
                throw new VcaException("未找到该订单详情 oderNo:" + storeOrderItemResponse.getOrderId());
            }
            for (StoreOrderInfo storeOrderInfo : map.get(storeOrderItemResponse.getOrderId())) {
                if (storeOrderInfo.getType().equals(4)) {
                    PreOrderCommonVo.PreOrderProductDetail preOrderProductDetail1 = JSONObject.parseObject(storeOrderInfo.getInfo(), PreOrderCommonVo.PreOrderProductDetail.class);
                    preOrderProductDetail1.setRefundStatus(storeOrderInfo.getRefundStatus());
                    preOrderProductDetail1.setOrderInfoStatus(getOrderInfoStatus(storeOrderInfo));
                    preOrderProductDetail.add(preOrderProductDetail1);
                } else {
                    storeOrderItemResponse.setLecturer(storeOrderInfo.getLecturer());
                    storeOrderItemResponse.setLecturerName(storeOrderInfo.getLecturerName());
                    storeOrderItemResponse.setLecturerPhone(shieldMobileKeyword(storeOrderInfo.getLecturerPhone()));
                    storeOrderItemResponse.setLecturerEmail(storeOrderInfo.getLecturerEmail());
                    storeOrderItemResponse.setCourseInfoDetails(JSONObject.parseObject(storeOrderInfo.getInfo(), PreOrderCommonVo.CourseInfoDetail.class));
                }
            }

            User user = userService.getById(storeOrder.getUid());
            if (ObjectUtil.isNull(user)) {
//                continue;
                throw new VcaException("该用户不存在 uid: " + storeOrder.getUid());
            }
            storeOrderItemResponse.setUserName(user.getNickname());
            storeOrderItemResponse.setUserPhone(user.getPhone());
            storeOrderItemResponse.setUserEmail(user.getEmail());
            storeOrderItemResponse.setPreOrderProductDetails(preOrderProductDetail);
            //订单状态
            storeOrderItemResponse.setStatusStr(getStatus(storeOrder));
//            storeOrderItemResponse.setStatus(storeOrder.getStatus());
            //支付方式
            storeOrderItemResponse.setPayTypeStr(getPayType(storeOrder.getPayType()));
            // 添加订单类型信息
            storeOrderItemResponse.setOrderType(getOrderTypeStr(storeOrder));
            detailResponseList.add(storeOrderItemResponse);

        }

//        //根据用户获取信息
//        List<Integer> userIdList = orderList.stream().map(StoreOrder::getUid).distinct().collect(Collectors.toList());
//        //订单用户信息
//        HashMap<Integer, User> userList = userService.getMapListInUid(userIdList);
        return detailResponseList;
    }

    /**
     * 获取订单类型（前端展示）
     * 订单类型:0-课程订单 1=套课订单 2=讲座订单 3=展览订单 4=商品订单
     *
     * @param storeOrder 订单
     * @return String
     */
    private String getOrderTypeStr(StoreOrder storeOrder) {
        String orderTypeFormat = "[{}订单]{}";
        String orderType = "";
//        // 核销
//        if (StrUtil.isNotBlank(storeOrder.getVerifyCode())) {
//            orderType = StrUtil.format(orderTypeFormat, "核销", "");
        if (storeOrder.getType().equals(0)) {
            orderType = StrUtil.format(orderTypeFormat, "课程", "");
        }
        if (storeOrder.getType().equals(1)) {
            orderType = StrUtil.format(orderTypeFormat, "套课", "");
        }
        if (storeOrder.getType().equals(2)) {
            orderType = StrUtil.format(orderTypeFormat, "讲座", "");
        }
        if (storeOrder.getType().equals(3)) {
            orderType = StrUtil.format(orderTypeFormat, "展览", "");
        }
        if (storeOrder.getType().equals(4)) {
            orderType = StrUtil.format(orderTypeFormat, "商品", "");
        }
        return orderType;
    }

    private String getOrderStatus(StoreOrder storeOrder) {
        if (!storeOrder.getPaid()) {
            return "待支付";
        }
        if (storeOrder.getIsDel() || storeOrder.getIsSystemDel()) {
            return "已取消";
        }
        if (storeOrder.getRefundStatus().equals(1)) {
            return "申请退款中";
        }
        if (storeOrder.getRefundStatus().equals(2)) {
            return "已退款";
        }
        if (storeOrder.getRefundStatus().equals(3)) {
            return "退款中";
        }
        if (storeOrder.getStatus().equals(0)) {
            return "待发货";
        }
        if (storeOrder.getStatus().equals(1)) {
            if (storeOrder.getType().equals(4)) {
                return "待收货";
            } else {
                return "待核销";
            }
        }
        if (storeOrder.getStatus().equals(2)) {
            return "待评价";
        }
        if (storeOrder.getStatus().equals(3)) {
            return "交易完成";
        }
        return "";
    }


    private String getOrderInfoStatus(StoreOrderInfo storeOrderInfo) {
        StoreOrder storeOrder = getByOrderId(storeOrderInfo.getOrderNo());
        if (!storeOrder.getPaid()) {
            return "未支付";
        }
        if (storeOrder.getIsDel() || storeOrder.getIsSystemDel()) {
            return "已取消";
        }
        if (storeOrderInfo.getRefundStatus().equals(1)) {
            return "申请退款中";
        }
        if (storeOrderInfo.getRefundStatus().equals(4)) {
            return "待退货";
        }
        if (storeOrderInfo.getRefundStatus().equals(5)) {
            return "退货中";
        }
        if (storeOrderInfo.getRefundStatus().equals(2)) {
            return "已退款";
        }
        if (storeOrderInfo.getRefundStatus().equals(3)) {
            return "退款中";
        }
        if (storeOrderInfo.getStatus().equals(0)) {
            return "待发货";
        }
        if (storeOrderInfo.getStatus().equals(1)) {
            if (storeOrderInfo.getType().equals(4)) {
                return "待收货";
            } else {
                return "待核销";
            }
        }
        if (storeOrderInfo.getStatus().equals(2)) {
            return "待评价";
        }
        if (storeOrderInfo.getStatus().equals(3) || storeOrderInfo.getRefundStatus().equals(6)) {
            return "交易完成";
        }
        return "";
    }

    /**
     * 格式化订单信息，对外输出一致
     *
     * @param storeOrderList List<StoreOrder> 订单列表
     * @return List<StoreOrderItemResponse>
     * @author Mr.Zhang
     * @since 2020-05-28
     */
//    private List<StoreOrderItemResponse> formatOrder(List<StoreOrder> storeOrderList) {
//        List<StoreOrderItemResponse> storeOrderItemResponseArrayList = new ArrayList<>();
//        if (null == storeOrderList || storeOrderList.size() < 1) {
//            return storeOrderItemResponseArrayList;
//        }
//        //店员id / 核销员id
//        List<Integer> clerkIdList = storeOrderList.stream().map(StoreOrder::getClerkId).distinct().collect(Collectors.toList());
//
//        //订单id集合
//        List<String> orderIdList = storeOrderList.stream().map(StoreOrder::getOrderId).distinct().collect(Collectors.toList());
//
//        //获取店员map
////        HashMap<Integer, SystemStoreStaff> systemStoreStaffList = systemStoreStaffService.getMapInId(clerkIdList);
//        HashMap<Integer, SystemAdmin> systemStoreStaffList = systemAdminService.getMapInId(clerkIdList);
//        //获取订单详情map
//        HashMap<String, List<StoreOrderInfoOldVo>> orderInfoList = StoreOrderInfoService.getMapInId(orderIdList);
//
//        //根据用户获取信息
//        List<Integer> userIdList = storeOrderList.stream().map(StoreOrder::getUid).distinct().collect(Collectors.toList());
//        //订单用户信息
//        HashMap<Integer, User> userList = userService.getMapListInUid(userIdList);
//
//        for (StoreOrder storeOrder : storeOrderList) {
//            StoreOrderItemResponse storeOrderItemResponse = new StoreOrderItemResponse();
//            BeanUtils.copyProperties(storeOrder, storeOrderItemResponse);
//            String storeName = "";
//            storeOrderItemResponse.setStoreName(storeName);
//
//            // 添加核销人信息
//            String clerkName = "";
//            if (systemStoreStaffList.containsKey(storeOrder.getClerkId())) {
//                clerkName = systemStoreStaffList.get(storeOrder.getClerkId()).getRealName();
//            }
//            storeOrderItemResponse.setProductList(orderInfoList.get(storeOrder.getId()));
//            storeOrderItemResponse.setTotalNum(storeOrder.getTotalNum());
//
//            //订单状态
//            storeOrderItemResponse.setStatusStr(getStatus(storeOrder));
//            storeOrderItemResponse.setStatus(storeOrder.getStatus());
//            //支付方式
//            storeOrderItemResponse.setPayTypeStr(getPayType(storeOrder.getPayType()));
//
//            storeOrderItemResponse.setRefundStatus(storeOrder.getRefundStatus());
//
//            storeOrderItemResponse.setClerkName(clerkName);
//
//            // 添加订单类型信息
//            String orderTypeFormat = "[{}订单]{}";
//            String orderType = "";
//            // 核销
//            if (StrUtil.isNotBlank(storeOrder.getVerifyCode())) {
//                orderType = StrUtil.format(orderTypeFormat, "核销", "");
//            }
//
//            if (StrUtil.isBlank(orderType)) {
//                orderType = StrUtil.format(orderTypeFormat, "普通", "");
//            }
//            storeOrderItemResponse.setOrderType(orderType);
//            storeOrderItemResponseArrayList.add(storeOrderItemResponse);
//        }
//        return storeOrderItemResponseArrayList;
//    }

    /**
     * 累计消费
     *
     * @param userId Integer 用户id
     * @return UserBalanceResponse
     * @author Mr.Zhang
     * @since 2020-06-10
     */
    @Override
    public BigDecimal getSumBigDecimal(Integer userId, String date) {
        QueryWrapper<StoreOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(pay_price) as pay_price").
                eq("paid", 1).
                eq("is_del", 0);
        if (null != userId) {
            queryWrapper.eq("uid", userId);
        }
        if (null != date) {
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(date);
            queryWrapper.between("create_time", dateLimit.getStartTime(), dateLimit.getEndTime());
        }
        StoreOrder storeOrder = dao.selectOne(queryWrapper);
        if (null == storeOrder || null == storeOrder.getPayPrice()) {
            return BigDecimal.ZERO;
        }
        return storeOrder.getPayPrice();
    }

    /**
     * 按开始结束时间分组订单
     *
     * @param date    String 时间范围
     * @param lefTime int 截取创建时间长度
     * @return HashMap<String, Object>
     * @author Mr.Zhang
     * @since 2020-05-16
     */
    @Override
    public List<StoreOrder> getOrderGroupByDate(String date, int lefTime) {
        QueryWrapper<StoreOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(pay_price) as pay_price", "left(create_time, " + lefTime + ") as orderId", "count(id) as id");
        if (StringUtils.isNotBlank(date)) {
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(date);
            queryWrapper.between("create_time", dateLimit.getStartTime(), dateLimit.getEndTime());
        }
        queryWrapper.groupBy("orderId").orderByAsc("orderId");
        return dao.selectList(queryWrapper);
    }

    /**
     * 退款
     *
     * @param request StoreOrderRefundRequest 退款参数
     * @return boolean
     * 这里只处理订单状态
     * 余额支付需要把余额给用户加回去
     * 其余处理放入redis中处理
     */
    @Override
    public Boolean refund(OrderRefunRequest request) {

        ArrayList<BigDecimal> amounts = new ArrayList<>();
        ArrayList<String> merOrderNos = new ArrayList<>();
        ArrayList<Integer> ids = new ArrayList<>();
        for (StoreOrderRefundRequest storeOrderRefundRequest : request.getStoreOrderRefundRequestList()) {
            amounts.add(storeOrderRefundRequest.getAmount());
            merOrderNos.add(storeOrderRefundRequest.getMerOrderNo());
        }
        List<StoreOrderInfo> storeOrderInfos = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().in(StoreOrderInfo::getMerOrderNo, merOrderNos));
        if (CollUtil.isEmpty(storeOrderInfos)) {
            throw new VcaException("未找到该订单信息");
        }
        StoreOrder storeOrder = getByOrderId(storeOrderInfos.get(0).getOrderNo());

        if (!storeOrder.getPaid()) {
            throw new VcaException("未支付无法退款");
        }
        //退款金额相加
        BigDecimal amountsNum = amounts.stream().reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
        if (amountsNum.compareTo(storeOrder.getPayPrice()) > 0) {
            throw new VcaException("退款金额大于支付金额，请修改退款金额");
        }
        if (amountsNum.compareTo(BigDecimal.ZERO) <= 0) {
            if (storeOrder.getPayPrice().compareTo(BigDecimal.ZERO) == 0) {
                throw new VcaException("退款金额不能为0，请修改退款金额");
            }
        }
        //退款
        List<UmsPayRefundVo> refundList = new ArrayList();
        request.getStoreOrderRefundRequestList().forEach(e -> {
            UmsPayRefundVo vo = new UmsPayRefundVo();
            BeanUtils.copyProperties(e, vo);
            refundList.add(vo);
        });

        Boolean refund = umsPayService.refund(refundList);
        if (refund) {
            storeOrderStatusService.createLog(storeOrder.getId(), "agreeRefund", 0, "管理员同意退款");
            redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_AFTER_REFUND_PRODUCT_BY_USER, storeOrder.getOrderId());
//            orderConsentRefund(storeOrder, storeOrderInfos);//消息通知
        }
        return refund;
    }

    /**
     * 退款处理
     *
     * @param request
     * @return
     */
    @Override
    public Boolean refundProcessing(OrderRefundProcessingRequest request) {

        StoreOrder storeOrder = getByOrderId(request.getOrderNo());

        if (ObjectUtil.isNull(storeOrder)) {
            throw new VcaException("订单不存在");
        }

        if (!storeOrder.getRefundStatus().equals(1)) {
            throw new VcaException("订单状态不为申请中 无法处理");
        }


        List<StoreOrderInfo> storeOrderInfos = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, request.getOrderNo()).eq(StoreOrderInfo::getRefundStatus, 1));

        if (request.getAuditType().equals(1)) {

            VcaProduct vcaProduct = vcaProductService.getById(storeOrderInfos.get(0).getProductId());
            if (ObjectUtil.isEmpty(vcaProduct)) {
                throw new VcaException("商品信息为空");
            }
            if (vcaProduct.getCid().equals(750)) {
                return giftCardRefund(storeOrder, storeOrderInfos);
            } else {
                String refundOrderNo = VcaUtil.getOrderNo("T");
                storeOrder.setReturnOrderNo(refundOrderNo);
                storeOrder.setRefundStatus(4);
                storeOrder.setAgreedReturnTime(DateUtil.nowDateTime());
                ArrayList<StoreOrderInfo> orderInfoArrayList = new ArrayList<>();
                for (StoreOrderInfo storeOrderInfo : storeOrderInfos) {
                    storeOrderInfo.setRefundStatus(4);
                    orderInfoArrayList.add(storeOrderInfo);
                }

                Boolean execute = transactionTemplate.execute(i -> {
                    updateById(storeOrder);
                    storeOrderInfoService.updateBatchById(orderInfoArrayList);
                    //订单记录增加
                    storeOrderStatusService.createLog(storeOrder.getId(), "refundProcessing", 1, "管理员已同意退款");
                    return Boolean.TRUE;
                });
                if (!execute) {
                    throw new VcaException("订单状态更新失败");
                } else {
                    redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_AFTER_RETURN_TIMEOUT_BY_USER, storeOrder.getId());
                    orderConsentReturn(storeOrder, orderInfoArrayList);//消息通知
                }
                return execute;
            }


        } else if (request.getAuditType().equals(0)) {
            storeOrder.setRefundStatus(6);
            storeOrder.setRefundReason(request.getNoRefundReasonWap());
            ArrayList<StoreOrderInfo> orderInfoArrayList = new ArrayList<>();
            ArrayList<UserCard> userCards = new ArrayList<>();
            VcaProduct vcaProduct = vcaProductService.getById(storeOrderInfos.get(0).getProductId());//todo 空指针判断
            for (StoreOrderInfo storeOrderInfo : storeOrderInfos) {
                storeOrderInfo.setRefundStatus(6);
                orderInfoArrayList.add(storeOrderInfo);
                if (vcaProduct.getCid().equals(750)) {
                    //礼品卡集合
                    List<UserCard> userCardList = userCardService.list(new LambdaQueryWrapper<UserCard>().eq(UserCard::getOrderId, storeOrderInfo.getMerOrderNo()));
                    for (UserCard userCard : userCardList) {
                        userCard.setStutus(0);
                        userCards.add(userCard);
                    }
                }
            }

            Boolean execute = transactionTemplate.execute(i -> {
                updateById(storeOrder);
                storeOrderInfoService.updateBatchById(orderInfoArrayList);
                if (CollUtil.isNotEmpty(userCards)) {
                    userCardService.updateBatchById(userCards);
                }
                //订单记录增加
                storeOrderStatusService.createLog(storeOrder.getId(), "refundProcessing", 1, "管理员拒绝退款 理由：" + request.getNoRefundReasonWap());
                return Boolean.TRUE;
            });
            if (!execute) {
                throw new VcaException("订单状态更新失败");
            } else {
                if (vcaProduct.getCid().equals(750)) {
                    orderRefuseRefund(storeOrder, storeOrderInfos);
                } else {
                    orderRefuseReturn(storeOrder, orderInfoArrayList);//  消息通知
                }

            }
            return execute;
        }
        return false;
    }


    /**
     * 礼品卡退款
     *
     * @return
     */
    public Boolean giftCardRefund(StoreOrder storeOrder, List<StoreOrderInfo> storeOrderInfoList) {

        //退款
        List<UmsPayRefundVo> refundList = new ArrayList();
        //如果实际支付金额为0则只变更状态 不需要退款
        if (storeOrder.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
            storeOrder.setRefundStatus(2);
            storeOrder.setRefundPrice(storeOrder.getPayPrice());
            storeOrder.setRefundReasonTime(DateUtil.nowDateTime());
            //更新集合
            ArrayList<StoreOrderInfo> storeOrderInfos = new ArrayList<>();

            ArrayList<UserCard> userCards = new ArrayList<>();
            for (StoreOrderInfo storeOrderInfo : storeOrderInfoList) {
                storeOrderInfo.setRefundStatus(2);
                storeOrderInfo.setRefundPrice(storeOrderInfo.getPayPrice());
                storeOrderInfo.setRefundReasonTime(DateUtil.nowDateTime());
                storeOrderInfos.add(storeOrderInfo);

                //礼品卡集合
                List<UserCard> userCardList = userCardService.list(new LambdaQueryWrapper<UserCard>().eq(UserCard::getOrderId, storeOrderInfo.getMerOrderNo()));
                for (UserCard userCard : userCardList) {
                    userCard.setStutus(2);
                    userCards.add(userCard);
                }

            }

            Boolean execute = transactionTemplate.execute(e -> {
                updateById(storeOrder);
                storeOrderInfoService.updateBatchById(storeOrderInfos);
                userCardService.updateBatchById(userCards);
                storeOrderStatusService.createLog(storeOrder.getId(), "giftCardRefund", 1, "退款成功！");
                return Boolean.TRUE;
            });
            if (execute) {
                return true;
            } else {
                throw new VcaException("订单退款失败！");
            }
        } else {
            for (StoreOrderInfo storeOrderInfo : storeOrderInfoList) {
                UmsPayRefundVo vo = new UmsPayRefundVo();
                vo.setAmount(storeOrderInfo.getPayPrice());
                vo.setMerOrderNo(storeOrderInfo.getMerOrderNo());
                refundList.add(vo);
            }
            Boolean refund = umsPayService.refund(refundList);
            if (refund) {
//                redisUtil.lPush(TaskConstants.PRODUCT_ORDER_CANCEL, storeOrder.getId());
////            orderConsentRefund(storeOrder, storeOrderInfos);//消息通知

                storeOrderTaskService.orderConsentRefund(getByOrderId(storeOrder.getOrderId()), storeOrderInfoService.getListByOrderNo(storeOrder.getOrderId()));
                return true;
            }
            {
                throw new VcaException("礼品卡退款失败");
            }
        }
    }

    @Override
    public Boolean getOrderInfoStatusIsAll(Integer RefundStatus, List<Integer> id) {
        //需要退款的商品
        List<StoreOrderInfo> storeOrderInfoByRefund = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().in(StoreOrderInfo::getId, id));

        //变更对应状态后的商品数
        List<StoreOrderInfo> storeOrderInfStatus = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, storeOrderInfoByRefund.get(0).getOrderNo()).eq(StoreOrderInfo::getRefundStatus, RefundStatus));

        //所有商品
        List<StoreOrderInfo> storeOrderInfoAll = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().ne(StoreOrderInfo::getOrderNo, storeOrderInfoByRefund.get(0).getOrderNo()));

        //如果所有商品状态一样返回true
        if (storeOrderInfStatus.size() == storeOrderInfoAll.size()) {
            return true;
        }
        return false;
    }

    /**
     * 同意退货消息通知
     */
    public Boolean orderConsentReturn(StoreOrder storeOrder, ArrayList<StoreOrderInfo> orderInfoList) {
        SystemNotification paySuccessOfEvent = systemNotificationService.getByMark(OrderRedisConstans.RETURN_GOODS_TO_SUCCESS);
        if (paySuccessOfEvent.getIsRoutine().equals(1)) {
            // TODO: 2022/12/30 生成小程序订阅消息
            //订单编号{{character_string2.DATA}}审核结果{{thing3.DATA}}温馨提示{{thing4.DATA}}
            HashMap<String, String> messageMap = new HashMap<>();
            messageMap.put("character_string2", storeOrder.getOrderId());
            messageMap.put("thing3", "审核通过");
            messageMap.put("thing4", "商家已经同意退货申请！");
            if (ObjectUtil.isNotNull(storeOrder.getUid())) {
                UserToken userToken = userTokenService.getTokenByUserId(storeOrder.getUid(), OrderRedisConstans.SYSTEM_TYPE_ROUTINE);
                templateMessageService.pushMiniTemplateMessage(paySuccessOfEvent.getRoutineId(), messageMap, userToken.getToken(), "pages/user-order-details/index?orderNo=" + storeOrder.getOrderId());
            }
        }
        if (paySuccessOfEvent.getIsWechat().equals(1)) {
            // TODO: 2023/1/3 公众号模板消息
            String name = orderInfoList.get(0).getName();
            if (orderInfoList.size() > 1) {
                if (name.length() > 13) {
                    name = name.substring(0, 13) + "等商品";
                }
            } else {
                if (name.length() > 16) {
                    name = name.substring(0, 16);
                }
            }
            //{{first.DATA}}订单号：{{keyword1.DATA}}商品名称：{{keyword2.DATA}}审核时间：{{keyword3.DATA}}订单金额：{{keyword4.DATA}}审核结果：{{keyword5.DATA}}{{remark.DATA}}
            HashMap<String, Object> message = new HashMap<>();
            message.put("first", "退货审核通知");
            message.put("keyword1", storeOrder.getOrderId());
            message.put("keyword2", name);
            message.put("keyword3", cn.hutool.core.date.DateUtil.format(new Date(), Constants.DATE_FORMAT));
            message.put("keyword4", storeOrder.getPayPrice().toPlainString());
            message.put("keyword5", "审核已通过");
            message.put("remark", "为您带来不便很抱歉！");
            orderPassReturnByPublicAccount(message, paySuccessOfEvent.getWechatId(), storeOrder);
        }
        if (paySuccessOfEvent.getIsSms().equals(1)) {
            // TODO: 2023/1/3 发送短信
            SmsTemplate smsTemplate = smsTemplateService.getDetail(paySuccessOfEvent.getSmsId());
            if (orderInfoList.size() > 1) {
                String name = orderInfoList.get(0).getName();
                if (name.length() > 13) {
                    name = orderInfoList.get(0).getName().substring(0, 13);
                }
                name = name + "等商品";
                smsOrderConsentReturn(storeOrder.getUid(), name, storeOrder, smsTemplate.getTempId());
            } else {
                String name = "";
                if (orderInfoList.get(0).getName().length() > 16) {
                    name = orderInfoList.get(0).getName().substring(0, 16);
                } else {
                    name = orderInfoList.get(0).getName();
                }
                smsOrderConsentReturn(storeOrder.getUid(), name, storeOrder, smsTemplate.getTempId());
            }

        }

        return Boolean.TRUE;
    }

    /**
     * 同意退货公众号通知
     *
     * @param message
     * @param wechatId
     * @param storeOrder
     */
    private void orderPassReturnByPublicAccount(HashMap<String, Object> message, Integer wechatId, StoreOrder storeOrder) {
        String pageUrl = "pages/user-order-details/index?orderNo=" + storeOrder.getOrderId();
        if (ObjectUtil.isNotNull(storeOrder.getUid())) {
            UserToken userToken = userTokenService.getTokenByUserId(storeOrder.getUid(), OrderRedisConstans.SYSTEM_TYPE_ROUTINE);
            if (ObjectUtil.isNotNull(userToken)) {
                templateMessageService.pushTemplatePublicMessage(pageUrl, wechatId, message, userToken.getToken());
            }
        }
    }

    /**
     * 订单同意退货短信模板
     *
     * @param userId
     * @param name
     * @param order
     * @param tempId
     */
    private void smsOrderConsentReturn(Integer userId, String name, StoreOrder order, String tempId) {
        String pageUrl = "pages/user-order-details/index?orderNo=" + order.getOrderId();
        if (ObjectUtil.isNotNull(userId)) {
            User user = userService.getById(userId);
            if (ObjectUtil.isNotNull(user.getPhone())) {
                smsService.sendReturnGoods(name, order.getOrderId(), user.getPhone(), tempId, pageUrl);
            }
        }
    }


    /**
     * 拒绝退货消息通知
     */
    public Boolean orderRefuseReturn(StoreOrder storeOrder, ArrayList<StoreOrderInfo> orderInfoList) {
        SystemNotification paySuccessOfEvent = systemNotificationService.getByMark(OrderRedisConstans.RETURN_GOODS_TO_ERROR);
        if (paySuccessOfEvent.getIsRoutine().equals(1)) {
            // TODO: 2022/12/30 生成小程序订阅消息
            //订单编号{{character_string2.DATA}}审核结果{{thing3.DATA}}温馨提示{{thing4.DATA}}
            HashMap<String, String> messageMap = new HashMap<>();
            messageMap.put("character_string2", storeOrder.getOrderId());
            messageMap.put("thing3", "商家已经拒绝退货申请");
            messageMap.put("thing4", "请前往小程序查看退货详情！");
            if (ObjectUtil.isNotNull(storeOrder.getUid())) {
                UserToken userToken = userTokenService.getTokenByUserId(storeOrder.getUid(), OrderRedisConstans.SYSTEM_TYPE_ROUTINE);
                templateMessageService.pushMiniTemplateMessage(paySuccessOfEvent.getRoutineId(), messageMap, userToken.getToken(), "pages/user-order-details/index?orderNo=" + storeOrder.getOrderId());
            }
        }
        if (paySuccessOfEvent.getIsWechat().equals(1)) {
            // TODO: 2023/1/3 公众号模板消息
            String name = orderInfoList.get(0).getName();
            if (orderInfoList.size() > 1) {
                if (name.length() > 13) {
                    name = name.substring(0, 13) + "等商品";
                }
            } else {
                if (name.length() > 16) {
                    name = name.substring(0, 16);
                }
            }
            //{{first.DATA}}订单号：{{keyword1.DATA}}商品名称：{{keyword2.DATA}}审核时间：{{keyword3.DATA}}订单金额：{{keyword4.DATA}}审核结果：{{keyword5.DATA}}{{remark.DATA}}
            HashMap<String, Object> message = new HashMap<>();
            message.put("first", "退货审核通知");
            message.put("keyword1", storeOrder.getOrderId());
            message.put("keyword2", name);
            message.put("keyword3", cn.hutool.core.date.DateUtil.format(new Date(), Constants.DATE_FORMAT));
            message.put("keyword4", storeOrder.getPayPrice().toPlainString());
            message.put("keyword5", "审核未通过");
            message.put("remark", "为您带来不便很抱歉！");
            orderNotPassReturnByPublicAccount(message, paySuccessOfEvent.getWechatId(), storeOrder);
        }
        if (paySuccessOfEvent.getIsSms().equals(1)) {
            // TODO: 2023/1/3 发送短信
            SmsTemplate smsTemplate = smsTemplateService.getDetail(paySuccessOfEvent.getSmsId());
            if (orderInfoList.size() > 1) {
                String name = orderInfoList.get(0).getName();
                if (name.length() > 13) {
                    name = orderInfoList.get(0).getName().substring(0, 13);
                }
                name = name + "等商品";
                smsOrderRefuseReturn(storeOrder.getUid(), name, storeOrder, smsTemplate.getTempId());
            } else {
                String name = "";
                if (orderInfoList.get(0).getName().length() > 16) {
                    name = orderInfoList.get(0).getName().substring(0, 16);
                } else {
                    name = orderInfoList.get(0).getName();
                }
                smsOrderRefuseReturn(storeOrder.getUid(), name, storeOrder, smsTemplate.getTempId());
            }

        }

        return Boolean.TRUE;
    }


    /**
     * 拒绝退货公众号通知
     *
     * @param message
     * @param wechatId
     * @param storeOrder
     */
    private void orderNotPassReturnByPublicAccount(HashMap<String, Object> message, Integer wechatId, StoreOrder storeOrder) {
        String pageUrl = "pages/user-order-details/index?orderNo=" + storeOrder.getOrderId();
        if (ObjectUtil.isNotNull(storeOrder.getUid())) {
            UserToken userToken = userTokenService.getTokenByUserId(storeOrder.getUid(), OrderRedisConstans.SYSTEM_TYPE_ROUTINE);
            if (ObjectUtil.isNotNull(userToken)) {
                templateMessageService.pushTemplatePublicMessage(pageUrl, wechatId, message, userToken.getToken());
            }
        }
    }


    /**
     * 订单拒绝退货短信模板
     *
     * @param userId
     * @param name
     * @param order
     * @param tempId
     */
    private void smsOrderRefuseReturn(Integer userId, String name, StoreOrder order, String tempId) {
        String pageUrl = "pages/user-order-details/index?orderNo=" + order.getOrderId();
        if (ObjectUtil.isNotNull(userId)) {
            User user = userService.getById(userId);
            if (ObjectUtil.isNotNull(user.getPhone())) {
                smsService.sendReturnGoods(name, order.getOrderId(), user.getPhone(), tempId, pageUrl);
            }
        }
    }


    /**
     * 拒绝退款消息通知
     *
     * @param storeOrder
     * @return
     */
    public Boolean orderRefuseRefund(StoreOrder storeOrder, List<StoreOrderInfo> orderInfoList) {
        SystemNotification paySuccessOfEvent = systemNotificationService.getByMark(OrderRedisConstans.REFUND_ORDER_TO_ERROR);
        if (paySuccessOfEvent.getIsRoutine().equals(1)) {
            // TODO: 2022/12/30 生成小程序订阅消息
            //订单号{{character_string1.DATA}}申请时间{{time2.DATA}}退款原因{{thing3.DATA}}审核结果{{thing4.DATA}}
            HashMap<String, String> messageMap = new HashMap<>();
            messageMap.put("character_string1", storeOrder.getOrderId());
            messageMap.put("time2", cn.hutool.core.date.DateUtil.format(storeOrder.getRefundApplicationTime(), Constants.DATE_FORMAT));
            messageMap.put("thing3", storeOrder.getRefundReasonWap());
            messageMap.put("thing4", "审核不通过");
            if (ObjectUtil.isNotNull(storeOrder.getUid())) {
                UserToken userToken = userTokenService.getTokenByUserId(storeOrder.getUid(), OrderRedisConstans.SYSTEM_TYPE_ROUTINE);
                templateMessageService.pushMiniTemplateMessage(paySuccessOfEvent.getRoutineId(), messageMap, userToken.getToken(), "pages/user-order-details/index?orderNo=" + storeOrder.getOrderId());
            }
        }
        if (paySuccessOfEvent.getIsWechat().equals(1)) {
            // TODO: 2023/1/3 公众号模板消息
            //{{first.DATA}}申请时间：{{keyword1.DATA}}原订单编号：{{keyword2.DATA}}退款金额：{{keyword3.DATA}}审核结果：{{keyword4.DATA}}{{remark.DATA}}
            HashMap<String, Object> message = new HashMap<>();
            message.put("first", "拒绝退款通知");
            message.put("keyword1", cn.hutool.core.date.DateUtil.format(storeOrder.getRefundApplicationTime(), Constants.DATE_FORMAT));
            message.put("keyword2", storeOrder.getOrderId());
            message.put("keyword3", storeOrder.getPayPrice().toPlainString());
            message.put("keyword4", "审核未通过");
            message.put("remark", "为您带来不便很抱歉！");
            orderRefuseRefundByPublicAccount(message, paySuccessOfEvent.getWechatId(), storeOrder);
        }
        if (paySuccessOfEvent.getIsSms().equals(1)) {
            // TODO: 2023/1/3 发送短信
            SmsTemplate smsTemplate = smsTemplateService.getDetail(paySuccessOfEvent.getSmsId());
            if (orderInfoList.size() > 1) {
                String name = orderInfoList.get(0).getName();
                if (name.length() > 13) {
                    name = orderInfoList.get(0).getName().substring(0, 13);
                }
                name = name + "等商品";
                smsOrderRefuseRefund(storeOrder.getUid(), name, storeOrder, smsTemplate.getTempId());
            } else {
                String name = "";
                if (orderInfoList.get(0).getName().length() > 16) {
                    name = orderInfoList.get(0).getName().substring(0, 16);
                } else {
                    name = orderInfoList.get(0).getName();
                }
                smsOrderRefuseRefund(storeOrder.getUid(), name, storeOrder, smsTemplate.getTempId());
            }

        }

        return Boolean.TRUE;
    }


    /**
     * 拒绝退款公众号消息通知
     *
     * @param message
     * @param wechatId
     * @param storeOrder
     */
    private void orderRefuseRefundByPublicAccount(HashMap<String, Object> message, Integer wechatId, StoreOrder storeOrder) {
        String pageUrl = "pages/user-order-details/index?orderNo=" + storeOrder.getOrderId();
        UserToken token = userTokenService.getTokenByUserId(storeOrder.getUid(), OrderRedisConstans.SYSTEM_TYPE_ROUTINE);
        if (ObjectUtil.isNotNull(token)) {
            templateMessageService.pushTemplatePublicMessage(pageUrl, wechatId, message, token.getToken());
        }
    }

    /**
     * 订单拒绝退款短信模板
     *
     * @param userId
     * @param name
     * @param order
     * @param tempId
     */
    private void smsOrderRefuseRefund(Integer userId, String name, StoreOrder order, String tempId) {
        String pageUrl = "pages/user-order-details/index?orderNo=" + order.getOrderId();
        if (ObjectUtil.isNotNull(userId)) {
            User user = userService.getById(userId);
            if (ObjectUtil.isNotNull(user.getPhone())) {
                smsService.sendOrderRefund(name, order.getOrderId(), user.getPhone(), tempId, pageUrl);
            }
        }
    }

    /**
     * 订单详情（PC）
     *
     * @param id 订单ID
     * @return StoreOrderInfoResponse
     */
    @Override
    public StoreOrderInfoResponse info(Integer id) {
        StoreOrder storeOrder = getById(id);

//        if (storeOrder.getIsSystemDel() || ObjectUtil.isNull(storeOrder)) {
//            throw new VcaException("未找到对应订单信息");
//        }
        if (ObjectUtil.isNull(storeOrder)) {
            throw new VcaException("未找到对应订单信息");
        }

        //订单详情
        List<StoreOrderInfo> storeOrderInfos = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, storeOrder.getOrderId()));

        //是否核销map
        HashMap<Long, String> integerIntegerHashMap = new HashMap<>();
        HashMap<Long, Integer> integerIntegerHashMap1 = new HashMap<>();


        StoreOrderInfoResponse storeOrderInfoResponse = new StoreOrderInfoResponse();
        BeanUtils.copyProperties(storeOrder, storeOrderInfoResponse);
        storeOrderInfoResponse.setPhone(storeOrder.getUserPhone());
        List<PreOrderCommonVo.PreOrderProductDetail> preOrderProductDetails = new ArrayList<>();
        for (StoreOrderInfo storeOrderInfo : storeOrderInfos) {
            //预约人信息
            storeOrderInfoResponse.setLecturerName(storeOrderInfo.getLecturerName());
            storeOrderInfoResponse.setLecturer(storeOrderInfo.getLecturer());
            storeOrderInfoResponse.setLecturerPhone(storeOrderInfo.getLecturerPhone());
            storeOrderInfoResponse.setLecturerEmail(storeOrderInfo.getLecturerEmail());
            storeOrderInfoResponse.setSchedulingDate(storeOrderInfo.getSchedulingDate());
            storeOrderInfoResponse.setSchedulingEndTime(storeOrderInfo.getSchedulingEndTime());
            storeOrderInfoResponse.setSchedulingStartTime(storeOrderInfo.getSchedulingStartTime());

            if (storeOrderInfo.getType().equals(4)) {
                PreOrderCommonVo.PreOrderProductDetail preOrderProductDetail = JSONObject.parseObject(storeOrderInfo.getInfo(), PreOrderCommonVo.PreOrderProductDetail.class);
                VcaProduct vcaProduct = vcaProductService.getById(storeOrderInfo.getProductId());
                storeOrderInfoResponse.setIsGiftCard(vcaProduct.getCid().equals(750) ? 1 : 0);
                preOrderProductDetail.setRefundStatus(storeOrderInfo.getRefundStatus());
                preOrderProductDetail.setOrderInfoStatus(getOrderInfoStatus(storeOrderInfo));
                preOrderProductDetail.setPayPrice(storeOrderInfo.getPayPrice());

                if(vcaProduct.getCid().equals(750)){
                    LambdaQueryWrapper<UserCard> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.eq(UserCard::getOrderId, storeOrderInfo.getMerOrderNo());
                    List<UserCard> list = userCardService.list(lambdaQueryWrapper);
                    List<String> tmp = new ArrayList<>();
                    if(ObjectUtil.isNotEmpty(list)){
                        list.forEach(userCard -> {
                            tmp.add(userCard.getCardNo());
                        });
                        preOrderProductDetail.setCardNos(tmp);
                    }
                }

                preOrderProductDetails.add(preOrderProductDetail);
            } else {
                //套课特殊处理
                if (storeOrderInfo.getType().equals(1)) {
                    integerIntegerHashMap.put(storeOrderInfo.getTaokeAboutCourseId(), getOrderInfoStatus(storeOrderInfo));
                    integerIntegerHashMap1.put(storeOrderInfo.getTaokeAboutCourseId(), storeOrderInfo.getStatus());
                } else {
                    integerIntegerHashMap.put(storeOrderInfo.getMainId(), getOrderInfoStatus(storeOrderInfo));
                    integerIntegerHashMap1.put(storeOrderInfo.getMainId(), storeOrderInfo.getStatus());
                }
                PreOrderCommonVo.CourseInfoDetail courseInfoDetail = JSONObject.parseObject(storeOrderInfo.getInfo(), PreOrderCommonVo.CourseInfoDetail.class);
                if (!storeOrderInfo.getType().equals(1)) {
                    courseInfoDetail.getSchedulings().get(0).setCourseAddress(JSONObject.parseObject(storeOrderInfo.getAddress().replace("[", "").replace("]", ""), HashMap.class));
                }
                for (PreOrderCommonVo.CourseInfoDetail.Scheduling scheduling : courseInfoDetail.getSchedulings()) {

                    //不为空则为套课
                    if (ObjectUtil.isNotNull(scheduling.getCourseId())) {
                        scheduling.setIsWriteOff(integerIntegerHashMap1.get(scheduling.getCourseId()));
                        scheduling.setOrderInfoStatus(integerIntegerHashMap.get(scheduling.getCourseId()));
                        scheduling.setPayPrice(storeOrderInfo.getPayPrice());
                    } else {
                        scheduling.setIsWriteOff(integerIntegerHashMap1.get(courseInfoDetail.getMainId()));
                        scheduling.setOrderInfoStatus(integerIntegerHashMap.get(courseInfoDetail.getMainId()));
                        scheduling.setPayPrice(storeOrderInfo.getPayPrice());
                    }
                }
                storeOrderInfoResponse.setCourseInfoDetails(courseInfoDetail);

                //礼品卡 卡号
                StoreOrder order = storeOrderService.getOne(new LambdaQueryWrapper<StoreOrder>().eq(StoreOrder::getOrderId, storeOrderInfo.getOrderNo()));
                    PreOrderCommonVo.PreOrderProductDetail preOrderProductDetail = new PreOrderCommonVo.PreOrderProductDetail();
                if(ObjectUtil.isNotNull(order.getCouponId())&&order.getCouponId()!=0){
                    LambdaQueryWrapper<UserCard> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.eq(UserCard::getId, order.getCouponId());
                    List<UserCard> list = userCardService.list(lambdaQueryWrapper);
                    List<String> tmp = new ArrayList<>();
                    if(ObjectUtil.isNotEmpty(list)){
                        list.forEach(userCard -> {
                            tmp.add(userCard.getCardNo());
                        });
                        preOrderProductDetail.setCardNos(tmp);
                    }
                preOrderProductDetails.add(preOrderProductDetail);
                }

            }
        }
        storeOrderInfoResponse.setPreOrderProductDetails(preOrderProductDetails);
        storeOrderInfoResponse.setLecturerNum(1);
        storeOrderInfoResponse.setPayTypeStr(getPayType(storeOrder.getPayType()));
        storeOrderInfoResponse.setStatusStr(getStatus(storeOrder));
        // 添加订单类型信息
        storeOrderInfoResponse.setOrderType(getOrderTypeStr(storeOrder));

        if (ObjectUtil.isNotEmpty(storeOrderInfoResponse.getType()) && storeOrderInfoResponse.getType().equals(2)) {
            TalkAdminResponse talk = talkService.getTalk(storeOrderInfoResponse.getCourseInfoDetails().getMainId());
            storeOrderInfoResponse.setTalkType(talk.getTalkType());
        }

        //用户信息
        User user = userService.getById(storeOrder.getUid());
        storeOrderInfoResponse.setUserName(user.getNickname());
        storeOrderInfoResponse.setUserPhone(user.getPhone());
        storeOrderInfoResponse.setUserEmail(user.getEmail());


        //物流状态
        if (storeOrder.getStatus() > 0 && storeOrder.getType().equals(4) && storeOrderInfoResponse.getIsGiftCard().equals(0) && StringUtils.isNotEmpty(storeOrder.getMasterWaybillNo())) {
            ResponseCancel orderRouting = sfService.getOrderRouting("",storeOrder.getOrderId(), 1);
            if (ObjectUtil.isNotEmpty(orderRouting) && ObjectUtil.isNotEmpty(orderRouting.getMsgData())) {
                Map<String, Object> innerMap = orderRouting.getMsgData().getInnerMap();
                JSONArray jsonArray = (JSONArray) innerMap.get("routeResps");
                JSONObject jsonObject = (JSONObject) jsonArray.get(0);
                JSONArray routes = (JSONArray) jsonObject.get("routes");
                if (ObjectUtil.isNotEmpty(routes)) {
                    List<Routes> routesList = JSONObject.parseArray(routes.toJSONString(), Routes.class);
                    List<Routes> collect = routesList.stream().sorted(Comparator.comparing(Routes::getAcceptTime).reversed()).collect(Collectors.toList());
                    storeOrderInfoResponse.setLogisticsStatus(collect.get(0).getRemark());
                } else {
                    storeOrderInfoResponse.setLogisticsStatus("未揽收或寄件时间超过3个月！");
                }
            }
        }
        return storeOrderInfoResponse;
    }

    /**
     * 发送货物
     *
     * @param request StoreOrderSendRequest 发货参数
     * @return boolean
     * @author Mr.Zhang
     * @since 2020-06-10
     */
    @Override
    public SendResponse send(StoreOrderSendRequest request) {
        String monthlyCard = systemConfigService.getValueByKey(Constants.MONTHLY_CARD);
        //查询订单信息
        LambdaQueryWrapper<StoreOrder> storeOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        storeOrderLambdaQueryWrapper.eq(StoreOrder::getId, request.getId());
        StoreOrder storeOrder = dao.selectOne(storeOrderLambdaQueryWrapper);

        if (ObjectUtil.isNull(storeOrder)) {
            throw new VcaException("订单不存在!");
        }
        //订单校验
        if (storeOrder.getIsDel()) throw new VcaException("订单已删除,不能发货!");
        if (storeOrder.getStatus() > 0) throw new VcaException("订单已发货请勿重复操作!");
        //查询获取订单详情信息
        LambdaQueryWrapper<StoreOrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StoreOrderInfo::getOrderNo, request.getOrderNo());
        List<StoreOrderInfo> storeOrderInfoList = StoreOrderInfoService.list(lambdaQueryWrapper);
        if (CollUtil.isEmpty(storeOrderInfoList)) {
            throw new VcaException("未找到该订单详情!");
        }
        SendResponse sendResponse = new SendResponse();
        // 1发货 2无需物流
        if (request.getType().equals("2")) {//todo 判断是否已经发货
            ArrayList<StoreOrderInfo> storeOrderInfos = new ArrayList<>();
            for (StoreOrderInfo storeOrderInfo : storeOrderInfoList) {
                storeOrderInfo.setStatus(3);
                storeOrderInfos.add(storeOrderInfo);
            }
            String afterSalesTime = systemConfigService.getValueByKey(Constants.AFTER_SALES_TIME);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            Date calendarTime = calendar.getTime();
            Date addDays = DateUtils.addDays(calendarTime, Integer.parseInt(afterSalesTime) + 1);
            storeOrder.setStatus(3);
            storeOrder.setClosingTime(new Date());
            storeOrder.setAfterSalesDeadline(addDays);
            Boolean execute = transactionTemplate.execute(i -> {
                dao.updateById(storeOrder);
                storeOrderInfoService.updateBatchById(storeOrderInfos);
                //订单记录增加
                storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_LOG_EXPRESS, 0, "已收货 无需物流");
                return Boolean.TRUE;
            });
            if (!execute) {
                throw new VcaException("订单状态变更失败");
            }
            sendResponse.setCode("S0000");
            sendResponse.setMsg("发货成功");
            sendResponse.setType(true);
            return sendResponse;
        } else if (request.getType().equals("1")) {


            StringBuilder ProductName = new StringBuilder();
            for (int i = 0; i < storeOrderInfoList.size(); i++) {
                ProductName.append(storeOrderInfoList.get(i).getName()).append(" ");
            }
            //顺丰下单参数实体
            MsgData md = new MsgData();
            //托寄物信息
            List<CargoDetail> cargoDetailList = new ArrayList<>();
            CargoDetail cargoDetail = new CargoDetail();
            cargoDetail.setName(ProductName.toString());
            cargoDetailList.add(cargoDetail);
            //收寄方信息
            ArrayList<ContactInfo> contactInfos = new ArrayList<>();
            //收件人信息
            ContactInfo addresseeInfo = new ContactInfo();
            //寄件人信息
            ContactInfo senderInfo = new ContactInfo();

            addresseeInfo.setContactType(2);
            addresseeInfo.setContact(storeOrder.getRealName());
            addresseeInfo.setMobile(storeOrder.getUserPhone());
            addresseeInfo.setTel(storeOrder.getUserPhone());
            addresseeInfo.setCountry("CN");
            addresseeInfo.setProvince(storeOrder.getProvince());
            addresseeInfo.setCity(storeOrder.getCity());
            addresseeInfo.setCounty(storeOrder.getDistrict());
            addresseeInfo.setAddress(storeOrder.getDetail());
            contactInfos.add(addresseeInfo);

            //寄件方信息

            senderInfo.setContactType(1);
            senderInfo.setContact(request.getToName());
            senderInfo.setMobile(request.getToTel());
            senderInfo.setTel(request.getToTel());
            senderInfo.setCountry("CN");
            senderInfo.setProvince(getSystemConfigName(Constants.CONFIG_EXPORT_TO_PROVINCE));
            senderInfo.setCity(getSystemConfigName(Constants.CONFIG_EXPORT_TO_CITY));
            senderInfo.setCounty(getSystemConfigName(Constants.CONFIG_EXPORT_TO_DISTRICT));
            senderInfo.setAddress(getSystemConfigName(Constants.CONFIG_EXPORT_TO_DETAIL));
            contactInfos.add(senderInfo);

            md.setLanguage("zh-CN");
            md.setOrderId(request.getOrderNo()); // 订单Id
            md.setCargoDetails(cargoDetailList);
            md.setContactInfoList(contactInfos);
            md.setMonthlyCard(monthlyCard);
            md.setExpressTypeId(1);
            md.setParcelQty(1);
            md.setIsDocall(1);
            md.setIsReturnRoutelabel(1);
            logger.info("发货下单请求参数：" + md);
            //调用第三方 返回数据
            ResponseCancel responseCreate = sfUtil.fopReceLtlCreateOrder(md, disable);
            //判断第三方是否成功  成功则拿到运单号 失败返回
            if (responseCreate.getSuccess()) {
                JSONObject msgData = responseCreate.getMsgData();
                Map<String, Object> innerMap = msgData.getInnerMap();
                JSONArray jsonArray = (JSONArray) innerMap.get("waybillNoInfoList");
                List<WaybillNoInfo> statusList = JSONObject.parseArray(jsonArray.toJSONString(), WaybillNoInfo.class);
                String masterWaybillNo = "";
                String branchWaybillNo = "";
                for (int i = 0; i < statusList.size(); i++) {
                    if (statusList.get(i).getWaybillType().equals(1)) {
                        masterWaybillNo = statusList.get(i).getWaybillNo();
                    } else {
                        branchWaybillNo = statusList.get(i).getWaybillNo();
                    }
                }

//            LoginUserVo loginUserVo = SecurityUtil.getLoginUserVo();
//            SystemAdmin currentAdmin = loginUserVo.getUser();
                Express express = expressService.getByCode(Constants.SF);
                //更新数据
                storeOrder.setDeliveryCode(express.getCode());
                storeOrder.setDeliveryName(express.getName());
                storeOrder.setMasterWaybillNo(masterWaybillNo);
                storeOrder.setStatus(1);
                storeOrder.setDeliverySfStatus(1);
                storeOrder.setDeliveryType("快递");
                storeOrder.setDeliveryTime(new Date());

                ArrayList<StoreOrderInfo> storeOrderInfos = new ArrayList<>();
                for (StoreOrderInfo storeOrderInfo : storeOrderInfoList) {
                    storeOrderInfo.setStatus(1);
                    storeOrderInfos.add(storeOrderInfo);
                }

                sendResponse.setCode(responseCreate.getErrorCode());
                sendResponse.setMsg("发货成功");
                sendResponse.setType(true);
                sendResponse.setMasterWaybillNo(masterWaybillNo);
                sendResponse.setBranchWaybillNo(branchWaybillNo);


                String message = Constants.ORDER_LOG_MESSAGE_EXPRESS.replace("{deliveryName}", express.getName()).replace("{deliveryCode}", storeOrder.getMasterWaybillNo());

                Boolean execute = transactionTemplate.execute(i -> {
                    dao.updateById(storeOrder);
                    storeOrderInfoService.updateBatchById(storeOrderInfos);
                    //订单记录增加
                    storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_LOG_EXPRESS, 0, message);
                    return Boolean.TRUE;
                });
                //消息通知
                orderSendPushMessage(storeOrder);
                if (!execute) throw new VcaException("已发货,更新订单状态失败！");
                //判断是否要打印电子面单
                if (request.getExpressRecordType().equals("1")) {
                    ExpressResponse expressResponse = getExpress(request.getId());
                    if (ObjectUtil.isNull(expressResponse) || ObjectUtil.isNull(expressResponse.getObj())) {
                        throw new VcaException("发货成功，但顺丰电子面单打印接口返回为空！");
                    }
                    JSONObject obj = expressResponse.getObj();
                    JSONArray jsonfilesList = (JSONArray) obj.get("files");
                    List<PrintFile> printFiles = JSONObject.parseArray(jsonfilesList.toJSONString(), PrintFile.class);
                    for (int i = 0; i < printFiles.size(); i++) {
                        sendResponse.setUrl(printFiles.get(i).getUrl());
                        sendResponse.setToken(printFiles.get(i).getToken());
                    }
                }

            } else {
                storeOrder.setDeliverySfStatus(0);
                dao.updateById(storeOrder);
                sendResponse.setCode(responseCreate.getErrorCode());
                sendResponse.setMsg(responseCreate.getErrorMsg());
                sendResponse.setType(false);
            }
            return sendResponse;
        }
        return sendResponse;
    }

    /**
     * 发货消息通知
     *
     * @param storeOrder
     * @return
     */
    public Boolean orderSendPushMessage(StoreOrder storeOrder) {
        List<StoreOrderInfo> orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, storeOrder.getOrderId()));
        SystemNotification paySuccessOfEvent = systemNotificationService.getByMark(OrderRedisConstans.ORDER_DELIVERY);
        if (paySuccessOfEvent.getIsRoutine().equals(1)) {
            //  生成小程序订阅消息
            orderSendPushMessageRoutine(storeOrder, orderInfoList, paySuccessOfEvent.getRoutineId());
        }
        if (paySuccessOfEvent.getIsWechat().equals(1)) {
            // TODO: 2023/1/3 公众号模板消息
            String name = orderInfoList.get(0).getName();
            if (orderInfoList.size() > 1 && orderInfoList.get(0).getType().equals(4)) {
                if (name.length() > 13) {
                    name = name.substring(0, 13) + "等商品";
                }
            } else {
                if (name.length() > 16) {
                    name = name.substring(0, 16);
                }
            }
            //{{first.DATA}}订单编号：{{keyword1.DATA}}商品名称：{{keyword2.DATA}}收货地址：{{keyword3.DATA}}快递单号：{{keyword4.DATA}}当前状态：{{keyword5.DATA}}{{remark.DATA}}
            HashMap<String, Object> message = new HashMap<>();
            message.put("first", "订单发货提醒");
            message.put("keyword1", storeOrder.getOrderId());
            message.put("keyword2", name);
            message.put("keyword3", storeOrder.getUserAddress());
            message.put("keyword4", storeOrder.getMasterWaybillNo());
            message.put("keyword5", "已发货");
            message.put("remark", "请留意快递信息！");
            orderSendByPublicAccount(message, paySuccessOfEvent.getWechatId(), storeOrder);
        }
        if (paySuccessOfEvent.getIsSms().equals(1)) {
            //  发送短信
            SmsTemplate smsTemplate = smsTemplateService.getDetail(paySuccessOfEvent.getSmsId());
            StoreOrderInfo orderInfo = orderInfoList.get(0);
            if (orderInfoList.size() > 1) {
                generateSmsOrderSend(storeOrder, orderInfo, smsTemplate, true);
            } else {
                generateSmsOrderSend(storeOrder, orderInfo, smsTemplate, false);
            }

        }
        return Boolean.TRUE;
    }

    /**
     * @Description:生成发货小程序订阅消息
     * @author:chenbing
     * @date 2022/12/30 15:55
     */
    private void orderSendPushMessageRoutine(StoreOrder storeOrder, List<StoreOrderInfo> orderInfoList, Integer routineId) {

        HashMap<String, String> messageMap = new HashMap<>();
        //下单时间{{time1.DATA}}订单编号{{character_string2.DATA}}发货时间{{time3.DATA}}订单状态{{phrase5.DATA}}快递单号{{character_string4.DATA}}
        messageMap.put("time1", cn.hutool.core.date.DateUtil.format(storeOrder.getCreateTime(), Constants.DATE_FORMAT));
        messageMap.put("character_string2", storeOrder.getOrderId());
        messageMap.put("time3", cn.hutool.core.date.DateUtil.format(storeOrder.getDeliveryTime(), Constants.DATE_FORMAT));
        messageMap.put("phrase5", getOrderStatus(storeOrder));
        messageMap.put("character_string4", storeOrder.getMasterWaybillNo());
        UserToken token = userTokenService.getTokenByUserId(storeOrder.getUid(), OrderRedisConstans.SYSTEM_TYPE_ROUTINE);
        if (ObjectUtil.isNotNull(token)) {
            templateMessageService.pushMiniTemplateMessage(routineId, messageMap, token.getToken(), "pages/user-order-details/index?orderNo=" + storeOrder.getOrderId());
        }


    }

    private void orderSendByPublicAccount(HashMap<String, Object> message, Integer wechatId, StoreOrder storeOrder) {
        String pageUrl = "pages/user-order-details/index?orderNo=" + storeOrder.getOrderId();
        UserToken token = userTokenService.getTokenByUserId(storeOrder.getUid(), OrderRedisConstans.SYSTEM_TYPE_ROUTINE);
        if (ObjectUtil.isNotNull(token)) {
            templateMessageService.pushTemplatePublicMessage(pageUrl, wechatId, message, token.getToken());
        }

    }

    /**
     * 订单发货短信通知
     *
     * @param order
     * @param storeOrderInfo
     * @param smsTemplate
     */
    private void generateSmsOrderSend(StoreOrder order, StoreOrderInfo storeOrderInfo, SmsTemplate smsTemplate, Boolean isMore) {
        String pageUrl = "pages/user-order-details/index?orderNo=" + order.getOrderId();
        if (ObjectUtil.isNotNull(order.getUid())) {
            User user = userService.getById(order.getUid());
            if (ObjectUtil.isNotNull(user.getPhone())) {
                if (isMore) {
                    String name = storeOrderInfo.getName();
                    if (name.length() > 13) {
                        name = storeOrderInfo.getName().substring(0, 13);
                    }
                    name = name + "等商品";

                    smsService.sendOrderDeliver(name, order.getMasterWaybillNo(), user.getPhone(), smsTemplate.getTempId(), pageUrl);
                } else {
                    String name = "";
                    if (storeOrderInfo.getName().length() > 15) {
                        name = storeOrderInfo.getName().substring(0, 15);
                    } else {
                        name = storeOrderInfo.getName();
                    }
                    smsService.sendOrderDeliver(name, order.getMasterWaybillNo(), user.getPhone(), smsTemplate.getTempId(), pageUrl);
                }

            }
        }
    }


    /**
     * 顺丰取消订单
     */
    public ResponseCancel cancel(String orderId) {
        //订单校验
        LambdaQueryWrapper<StoreOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StoreOrder::getOrderId, orderId);
        StoreOrder storeOrder = dao.selectOne(lambdaQueryWrapper);
        if (ObjectUtil.isNull(storeOrder)) {
            throw new VcaException("该订单不存在！");
        }
        if (storeOrder.getIsDel()) throw new VcaException("订单已删除");
        if (storeOrder.getStatus() != 1) throw new VcaException("该订单未发货或已收货");
        //取消订单参数
        MsgDataUpdate msgDataUpdate = new MsgDataUpdate();
        msgDataUpdate.setDealType(2);
        msgDataUpdate.setLanguage("zh-CN");
        msgDataUpdate.setOrderId(orderId);
        ResponseCancel responseCancel = sfUtil.fopReceLtlCancelOrder(msgDataUpdate, disable);
        if (responseCancel.getSuccess()) {
            JSONObject msgData = responseCancel.getMsgData();
            Integer resStatus = (Integer) msgData.get("resStatus");
            if (resStatus.equals(2)) {
                storeOrder.setDeliverySfStatus(2);
                dao.updateById(storeOrder);
            } else {
                storeOrder.setDeliverySfStatus(3);
                dao.updateById(storeOrder);
            }
        } else {
            storeOrder.setDeliverySfStatus(3);
            dao.updateById(storeOrder);
        }
        return responseCancel;
    }

    /**
     * 顺丰取消订单-拦截
     */
    public ResponseCancel intercept(String orderId) {
        //订单校验
        LambdaQueryWrapper<StoreOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StoreOrder::getOrderId, orderId);
        StoreOrder storeOrder = dao.selectOne(lambdaQueryWrapper);
        if (ObjectUtil.isNull(storeOrder)) {
            throw new VcaException("该订单不存在！");
        }
        if (storeOrder.getIsDel()) throw new VcaException("订单已删除");
        if (storeOrder.getStatus() != 1) throw new VcaException("该订单未发货或已收货");
        //取消订单参数
        MsgDataIntercept msgDataIntercept = new MsgDataIntercept();
        msgDataIntercept.setWaybillNo(storeOrder.getMasterWaybillNo());
        msgDataIntercept.setServiceCode("2");
        msgDataIntercept.setRole("1");
        msgDataIntercept.setPayMode("4");
        msgDataIntercept.setMonthlyCardNo("7551234567");
        ResponseCancel responseCancel = sfUtil.fopInterceptOrder(msgDataIntercept, disable);
        if (responseCancel.getSuccess()) {
            if ((Boolean) responseCancel.getMsgData().get("success")) {
                storeOrder.setDeliverySfStatus(4);
                dao.updateById(storeOrder);
            } else {
                storeOrder.setDeliverySfStatus(5);
                dao.updateById(storeOrder);
            }
        } else {
            storeOrder.setDeliverySfStatus(5);
            dao.updateById(storeOrder);
        }

        return responseCancel;
    }

    /**
     * 顺丰发货订单路由
     *
     * @param orderId
     * @return
     */
    public ResponseCancel getOrderRouting(Integer orderId) {
        LambdaQueryWrapper<StoreOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StoreOrder::getId, orderId);
        StoreOrder storeOrder = dao.selectOne(lambdaQueryWrapper);
        if (ObjectUtil.isNull(storeOrder)) {
            throw new VcaException("该订单不存在！");
        }
        if (storeOrder.getIsDel()) {
            throw new VcaException("订单已删除");
        }
        return sfUtil.fopReceLtlGetOrderRouting(storeOrder.getMasterWaybillNo(), disable);
    }

    /**
     * 电子面单
     *
     * @return
     */
    @Override
    public ExpressResponse getExpress(Integer orderId) {

        LambdaQueryWrapper<StoreOrder> storeOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        storeOrderLambdaQueryWrapper.eq(StoreOrder::getId, orderId);
        StoreOrder storeOrder = dao.selectOne(storeOrderLambdaQueryWrapper);

        MsgDataExpress msgDataExpress = new MsgDataExpress();
        ArrayList<Documents> documentsArrayList = new ArrayList<>();
        Documents documents = new Documents();
        documents.setMasterWaybillNo(storeOrder.getMasterWaybillNo());
        documentsArrayList.add(documents);

        msgDataExpress.setTemplateCode(systemConfigService.getValueByKey(Constants.TEMPLATE_CODE));
        msgDataExpress.setDocuments(documentsArrayList);
        msgDataExpress.setVersion("2.0");
        msgDataExpress.setFileType("pdf");
        msgDataExpress.setSync(true);
//        HashMap<String, Object> map = new HashMap<>();
//        map.put("encryptFlag", "1");
//        JSONObject extJson = new JSONObject(map);
//        msgDataExpress.setExtJson(extJson);
        ExpressResponse express = sfUtil.getExpress(msgDataExpress, disable);
        return express;
    }


    /**
     * 退款处理信息
     *
     * @param orderNo
     * @return
     */
    @Override
    public OrderRefundInfoResponse RefundInfo(String orderNo) {
        OrderRefundInfoResponse orderRefundInfoResponse = new OrderRefundInfoResponse();
        StoreOrder storeOrder = getByOrderId(orderNo);
        BeanUtils.copyProperties(storeOrder, orderRefundInfoResponse);
        orderRefundInfoResponse.setOrderNo(storeOrder.getOrderId());
        orderRefundInfoResponse.setRefundMethod("快递");

        //物流状态
        if (storeOrder.getRefundStatus().equals(5) && storeOrder.getType().equals(4)) {
            ResponseCancel orderRouting = sfService.getOrderRouting("",storeOrder.getOrderId(), 2);
            if (ObjectUtil.isNotEmpty(orderRouting) && ObjectUtil.isNotEmpty(orderRouting.getMsgData())) {
                Map<String, Object> innerMap = orderRouting.getMsgData().getInnerMap();
                JSONArray jsonArray = (JSONArray) innerMap.get("routeResps");
                JSONObject jsonObject = (JSONObject) jsonArray.get(0);
                JSONArray routes = (JSONArray) jsonObject.get("routes");
                if (ObjectUtil.isNotEmpty(routes)) {
                    List<Routes> routesList = JSONObject.parseArray(routes.toJSONString(), Routes.class);
                    List<Routes> collect = routesList.stream().sorted(Comparator.comparing(Routes::getAcceptTime).reversed()).collect(Collectors.toList());
                    orderRefundInfoResponse.setLogisticsStatus(collect.get(0).getRemark());
                } else {
                    orderRefundInfoResponse.setLogisticsStatus("未揽收或寄件时间超过3个月！");
                }
            }
        }


        LambdaQueryWrapper<StoreOrderInfo> storeOrderInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        storeOrderInfoLambdaQueryWrapper.eq(StoreOrderInfo::getOrderNo, orderNo);
        storeOrderInfoLambdaQueryWrapper.in(StoreOrderInfo::getRefundStatus, 1, 5);
        List<OrderInfoResponse> orderInfoResponseList = new ArrayList<>();
        for (StoreOrderInfo storeOrderInfo : storeOrderInfoService.list(storeOrderInfoLambdaQueryWrapper)) {
            OrderInfoResponse orderInfoResponse = new OrderInfoResponse();
            BeanUtils.copyProperties(storeOrderInfo, orderInfoResponse);
            orderInfoResponseList.add(orderInfoResponse);
        }
        orderRefundInfoResponse.setOrderInfoResponses(orderInfoResponseList);
        return orderRefundInfoResponse;
    }

    /**
     * 订单备注
     *
     * @param orderNo 订单编号
     * @param mark    备注
     * @return Boolean
     */
    @Override
    public Boolean mark(String orderNo, String mark) {
        StoreOrder storeOrder = getInfoException(orderNo);
        storeOrder.setRemark(mark);
        return updateById(storeOrder);
    }

    /**
     * 拒绝退款
     *
     * @param orderNo 订单编号
     * @param reason  String 原因
     * @return Boolean
     */
    @Override
    public Boolean refundRefuse(String orderNo, String reason) {
        if (StrUtil.isBlank(reason)) {
            throw new VcaException("请填写拒绝退款原因");
        }


        StoreOrder storeOrder = getInfoException(orderNo);


        ArrayList<StoreOrderInfo> storeOrderInfos = new ArrayList<>();
        for (StoreOrderInfo storeOrderInfo : storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, storeOrder.getOrderId()).eq(StoreOrderInfo::getRefundStatus, 5))) {
            storeOrderInfo.setRefundStatus(6);
            storeOrderInfo.setRefundReason(reason);
            storeOrderInfos.add(storeOrderInfo);
        }


//        User user = userService.getById(storeOrder.getUid());

        Boolean execute = transactionTemplate.execute(e -> {
            storeOrderInfoService.updateBatchById(storeOrderInfos);
            storeOrder.setRefundReason(reason);
            storeOrder.setRefundStatus(6);
            updateById(storeOrder);

            storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_LOG_REFUND_REFUSE, 1, "管理员拒绝退款 " + Constants.ORDER_LOG_MESSAGE_REFUND_REFUSE.replace("{reason}", reason));
            return Boolean.TRUE;
        });
        if (execute) {
            orderRefuseRefund(storeOrder, storeOrderInfos);//  消息通知
        }
        return execute;
    }


    /**
     * 查询单条
     *
     * @param storeOrder StoreOrder 订单参数
     * @return StoreOrder
     * @author Mr.Zhang
     * @since 2020-05-28
     */
    @Override
    public StoreOrder getInfoByEntity(StoreOrder storeOrder) {
        LambdaQueryWrapper<StoreOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.setEntity(storeOrder);
        return dao.selectOne(lambdaQueryWrapper);
    }

    /**
     * 获取订单快递信息
     *
     * @param orderNo 订单编号
     * @return LogisticsResultVo
     */
    @Override
    public LogisticsResultVo getLogisticsInfo(String orderNo) {
        StoreOrder info = getInfoException(orderNo);
        if (info.getType().equals(1)) {// 视频号订单
            Express express = expressService.getByName(info.getDeliveryName());
            if (ObjectUtil.isNotNull(express)) {
                info.setDeliveryCode(express.getCode());
            } else {
                info.setDeliveryCode("");
            }
        }
        return logisticService.info(info.getMasterWaybillNo(), null, Optional.ofNullable(info.getDeliveryCode()).orElse(""), info.getUserPhone());
    }

    /**
     * 订单 top 查询参数
     *
     * @param status 状态参数
     * @return 订单查询结果
     */
    @Override
    public Integer getTopDataUtil(Integer status, Integer userId) {
        LambdaQueryWrapper<StoreOrder> lqw = new LambdaQueryWrapper<>();
        orderUtils.statusApiByWhere(lqw, status);
        lqw.eq(StoreOrder::getUid, userId);
        return dao.selectCount(lqw);
    }

    /**
     * 改价
     *
     * @param orderNo  订单编号
     * @param price    修改后的价格
     * @param oldPrice 原支付金额
     */
    private Boolean orderEditPrice(String orderNo, BigDecimal price, BigDecimal oldPrice) {
        LambdaUpdateWrapper<StoreOrder> luw = new LambdaUpdateWrapper<>();
        luw.set(StoreOrder::getPayPrice, price);
        luw.set(StoreOrder::getBeforePayPrice, oldPrice);
        luw.set(StoreOrder::getIsAlterPrice, 1);
        luw.eq(StoreOrder::getOrderId, orderNo);
        luw.eq(StoreOrder::getPaid, false);
        return update(luw);
    }

    /**
     * 根据时间参数统计订单销售额
     *
     * @param dateLimit 时间区间
     * @param type      类型
     * @return 统计订单信息
     */
    @Override
    public StoreOrderStatisticsResponse orderStatisticsByTime(String dateLimit, Integer type) {
        StoreOrderStatisticsResponse response = new StoreOrderStatisticsResponse();
        // 根据开始时间和结束时间获取时间差 再根据时间差获取上一个时间段 查询当前和上一个时间段的数据 进行比较且返回
        dateLimitUtilVo dateRange = DateUtil.getDateLimit(dateLimit);
        String dateStartD = dateRange.getStartTime();
        String dateEndD = dateRange.getEndTime();
        int days = DateUtil.daysBetween(
                DateUtil.strToDate(dateStartD, Constants.DATE_FORMAT_DATE),
                DateUtil.strToDate(dateEndD, Constants.DATE_FORMAT_DATE)
        );
        // 同时间区间的上一个时间起点
        String perDateStart = DateUtil.addDay(
                DateUtil.strToDate(dateStartD, Constants.DATE_FORMAT_DATE), -days, Constants.DATE_FORMAT_START);
        // 当前时间区间
        String dateStart = DateUtil.addDay(
                DateUtil.strToDate(dateStartD, Constants.DATE_FORMAT_DATE), 0, Constants.DATE_FORMAT_START);
        String dateEnd = DateUtil.addDay(
                DateUtil.strToDate(dateEndD, Constants.DATE_FORMAT_DATE), 0, Constants.DATE_FORMAT_END);

        // 上一个时间段查询
        List<StoreOrder> orderPerList = getOrderPayedByDateLimit(perDateStart, dateStart);

        // 当前时间段
        List<StoreOrder> orderCurrentList = getOrderPayedByDateLimit(dateStart, dateEnd);
        double increasePrice = 0;
        if (type == 1) {
            double perSumPrice = orderPerList.stream().mapToDouble(e -> e.getPayPrice().doubleValue()).sum();
            double currentSumPrice = orderCurrentList.stream().mapToDouble(e -> e.getPayPrice().doubleValue()).sum();

            response.setChart(dao.getOrderStatisticsPriceDetail(new StoreDateRangeSqlPram(dateStart, dateEnd)));
            response.setTime(BigDecimal.valueOf(currentSumPrice).setScale(2, BigDecimal.ROUND_HALF_UP));
            // 当前营业额和上一个同比营业额增长区间
            increasePrice = currentSumPrice - perSumPrice;
            if (increasePrice <= 0) response.setGrowthRate(0);
            else if (perSumPrice == 0) response.setGrowthRate((int) increasePrice * 100);
            else response.setGrowthRate((int) ((increasePrice * perSumPrice) * 100));
        } else if (type == 2) {
            response.setChart(dao.getOrderStatisticsOrderCountDetail(new StoreDateRangeSqlPram(dateStart, dateEnd)));
            response.setTime(BigDecimal.valueOf(orderCurrentList.size()));
            increasePrice = orderCurrentList.size() - orderPerList.size();
            if (increasePrice <= 0) response.setGrowthRate(0);
            else if (orderPerList.size() == 0) response.setGrowthRate((int) increasePrice);
            else response.setGrowthRate((int) ((increasePrice / orderPerList.size()) * 100));
        }
        response.setIncreaseTime(increasePrice + "");
        response.setIncreaseTimeStatus(increasePrice >= 0 ? 1 : 2);
        return response;
    }

    /**
     * 获取用户当天的秒杀数量
     *
     * @param uid       用户uid
     * @param seckillId 秒杀商品id
     * @return 用户当天的秒杀商品订单数量
     */
    @Override
    public List<StoreOrder> getUserCurrentDaySecKillOrders(Integer uid, Integer seckillId) {
        String dayStart = DateUtil.nowDateTime(Constants.DATE_FORMAT_START);
        String dayEnd = DateUtil.nowDateTime(Constants.DATE_FORMAT_END);
        LambdaQueryWrapper<StoreOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(StoreOrder::getUid, uid);
        lqw.between(StoreOrder::getCreateTime, dayStart, dayEnd);
        lqw.eq(StoreOrder::getIsDel, false);
        return dao.selectList(lqw);
    }

    /**
     * 获取用户当前的砍价订单
     *
     * @param uid 用户uid
     * @return 用户当前的砍价订单
     */
    @Override
    public List<StoreOrder> getUserCurrentBargainOrders(Integer uid, Integer bargainId) {
        LambdaQueryWrapper<StoreOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(StoreOrder::getUid, uid);
        lqw.eq(StoreOrder::getIsDel, false);
        return dao.selectList(lqw);
    }

    /**
     * 获取用户当前的拼团订单
     *
     * @param uid 用户uid
     * @return 用户当前的拼团订单
     */
    @Override
    public List<StoreOrder> getUserCurrentCombinationOrders(Integer uid, Integer combinationId) {
        LambdaQueryWrapper<StoreOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(StoreOrder::getUid, uid);
        lqw.eq(StoreOrder::getIsDel, false);
        return dao.selectList(lqw);
    }

    @Override
    public StoreOrder getByOrderId(String orderId) {
        LambdaQueryWrapper<StoreOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(StoreOrder::getOrderId, orderId);
        return dao.selectOne(lqw);
    }

    /**
     * 获取面单默认配置信息
     *
     * @return ExpressSheetVo
     */
    @Override
    public ExpressSheetVo getDeliveryInfo() {
        return systemConfigService.getDeliveryInfo();
    }

    /**
     * 更新支付结果
     *
     * @param orderNo 订单编号
     * @return Boolean
     */
    @Override
    public Boolean updatePaid(String orderNo) {
        LambdaUpdateWrapper<StoreOrder> lqw = new LambdaUpdateWrapper<>();
        lqw.set(StoreOrder::getPaid, true);
        lqw.set(StoreOrder::getPayTime, DateUtil.nowDateTime());
        lqw.eq(StoreOrder::getOrderId, orderNo);
        lqw.eq(StoreOrder::getPaid, false);
        return update(lqw);
    }

    /**
     * 跟据订单号列表获取订单列表Map
     *
     * @param orderNoList 订单号列表
     * @return Map
     */
    @Override
    public Map<String, StoreOrder> getMapInOrderNo(List<String> orderNoList) {
        Map<String, StoreOrder> map = new HashMap<>();
        LambdaUpdateWrapper<StoreOrder> lqw = new LambdaUpdateWrapper<>();
        lqw.in(StoreOrder::getOrderId, orderNoList);
        List<StoreOrder> orderList = dao.selectList(lqw);
        orderList.forEach(order -> {
            map.put(order.getOrderId(), order);
        });
        return map;
    }

    /**
     * 获取推广订单总金额
     *
     * @param orderNoList 订单编号列表
     * @return BigDecimal
     */
    @Override
    public BigDecimal getSpreadOrderTotalPriceByOrderList(List<String> orderNoList) {
        LambdaQueryWrapper<StoreOrder> lqw = new LambdaQueryWrapper<>();
        lqw.select(StoreOrder::getPayPrice);
        lqw.in(StoreOrder::getOrderId, orderNoList);
        List<StoreOrder> orderList = dao.selectList(lqw);
        return orderList.stream().map(StoreOrder::getPayPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    /**
     * 获取所有收货订单id集合
     *
     * @return List<StoreOrder>
     */
    @Override
    public List<StoreOrder> findIdAndUidListByReceipt() {
        LambdaQueryWrapper<StoreOrder> lqw = new LambdaQueryWrapper<>();
        lqw.select(StoreOrder::getId, StoreOrder::getUid);
        lqw.eq(StoreOrder::getStatus, 2);
        lqw.eq(StoreOrder::getRefundStatus, 0);
        lqw.eq(StoreOrder::getIsDel, false);
        List<StoreOrder> orderList = dao.selectList(lqw);
        if (CollUtil.isEmpty(orderList)) {
            return CollUtil.newArrayList();
        }
        return orderList;
    }

    /**
     * @param userId           用户uid
     * @param pageParamRequest 分页参数
     * @return List
     */
    @Override
    public List<StoreOrder> findPaidListByUid(Integer userId, PageParamRequest pageParamRequest) {
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        LambdaQueryWrapper<StoreOrder> lqw = new LambdaQueryWrapper<>();
        lqw.eq(StoreOrder::getUid, userId);
        lqw.eq(StoreOrder::getPaid, true);
        lqw.eq(StoreOrder::getIsDel, false);
        lqw.lt(StoreOrder::getRefundStatus, 2);
        lqw.orderByDesc(StoreOrder::getId);
        return dao.selectList(lqw);
    }

    /**
     * 订单改价
     *
     * @param request 改价请求对象
     * @return 改价结果
     */
    @Override
    public Boolean updatePrice(StoreOrderUpdatePriceRequest request) {
        StoreOrder existOrder = getInfoException(request.getOrderNo());
        // 订单已支付
        if (existOrder.getPaid()) {
            throw new VcaException(StrUtil.format("订单号为 {} 的订单已支付", existOrder.getOrderId()));
        }
        if (existOrder.getIsAlterPrice()) {
            throw new VcaException("系统只支持一次改价");
        }
        // 修改价格和原来价格相同
        if (existOrder.getPayPrice().compareTo(request.getPayPrice()) == 0) {
            throw new VcaException(StrUtil.format("修改价格不能和原支付价格相同 原价 {} 修改价 {}", existOrder.getPayPrice(), request.getPayPrice()));
        }
        String oldPrice = existOrder.getPayPrice() + "";

        Boolean execute = transactionTemplate.execute(e -> {
            // 修改订单价格
            orderEditPrice(existOrder.getOrderId(), request.getPayPrice(), existOrder.getPayPrice());
            // 订单修改状态操作
            storeOrderStatusService.createLog(existOrder.getId(), Constants.ORDER_LOG_EDIT,
                    0,
                    Constants.RESULT_ORDER_EDIT_PRICE_LOGS.replace("${orderPrice}", oldPrice)
                            .replace("${price}", request.getPayPrice() + ""));
            return Boolean.TRUE;
        });
        if (!execute) {
            throw new VcaException(Constants.RESULT_ORDER_EDIT_PRICE_SUCCESS
                    .replace("${orderNo}", existOrder.getOrderId()).replace("${price}", request.getPayPrice() + ""));
        }
        // 发送改价短信提醒
        SystemNotification notification = systemNotificationService.getByMark(NotifyConstants.MODIFY_ORDER_PRICE_MARK);
        if (notification.getIsSms().equals(1)) {
            User user = userService.getById(existOrder.getUid());
            if (StrUtil.isNotBlank(user.getPhone())) {
                SmsTemplate smsTemplate = smsTemplateService.getDetail(notification.getSmsId());
                // 发送改价短信提醒
//                smsService.sendOrderEditPriceNotice(user.getPhone(), existOrder.getOrderId(), request.getPayPrice(), Integer.valueOf(smsTemplate.getTempId()));
            }
        }

        return execute;
    }

    /**
     * 订单取消（课程 讲座 展览）
     *
     * @param orderNo
     * @return
     */
    @Override
    public CommonResult orderCancel(String orderNo) {

        StoreOrder storeOrder = getByOrderId(orderNo);

        if (ObjectUtil.isNull(storeOrder)) {
            throw new VcaException("该订单不存在！");
        }

        if (storeOrder.getType().equals(4)) {
            throw new VcaException("该订单类型不支持取消");
        }

        if (storeOrder.getIsDel() || storeOrder.getIsSystemDel()) {
            throw new VcaException("该订单已取消");
        }

        if (!storeOrder.getRefundStatus().equals(0) || !storeOrder.getStatus().equals(1)) {
            throw new VcaException("订单状态不支持取消");
        }


        List<StoreOrderInfo> storeOrderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().in(StoreOrderInfo::getOrderNo, orderNo));
        for (StoreOrderInfo storeOrderInfo : storeOrderInfoList) {
            if (storeOrderInfo.getRefundStatus() == 1) {
                throw new VcaException("正在申请退款中");
            }

            if (storeOrderInfo.getRefundStatus() == 2) {
                throw new VcaException("订单已退款");
            }

            if (storeOrderInfo.getRefundStatus() == 3) {
                throw new VcaException("订单退款中");
            }
        }

        List<StoreOrderInfo> orderInfos = new ArrayList<>();


        //退款判断  如果不是后台赠送并且金额不为0 则调用退款接口并更新订单状态为退款中
        if (storeOrder.getUserType().equals(0) && storeOrder.getPayPrice().compareTo(BigDecimal.ZERO) > 0) {
            List<UmsPayRefundVo> refundList = new ArrayList();

            for (StoreOrderInfo storeOrderInfo : storeOrderInfoList) {
                if (storeOrderInfo.getStatus().equals(1) && storeOrderInfo.getRefundStatus().equals(0)) {
                    UmsPayRefundVo umsPayRefundVo = new UmsPayRefundVo();
                    umsPayRefundVo.setMerOrderNo(storeOrderInfo.getMerOrderNo());
                    umsPayRefundVo.setAmount(storeOrderInfo.getPayPrice());
                    refundList.add(umsPayRefundVo);
                }
            }
            if (umsPayService.refund(refundList)) {
                // 退款task
                storeOrderStatusService.createLog(storeOrder.getId(), "orderCancel", 0, "订单取消");
                redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_ADMIN_ORDER_CANCEL_BY_USER, storeOrder.getOrderId());
                return CommonResult.success(true);

            } else {
                return CommonResult.failed("取消失败");
            }
        } else {
            //为后台赠送或金额为0 则直接修改订单状态为已退款 并把退款后续操作放进redis
            for (StoreOrderInfo storeOrderInfo : storeOrderInfoList) { //更新info表状态
                if (storeOrderInfo.getStatus().equals(1) && storeOrderInfo.getRefundStatus().equals(0)) {
                    storeOrderInfo.setRefundStatus(2);
                    storeOrderInfo.setRefundReasonTime(DateUtil.nowDateTime());
                    orderInfos.add(storeOrderInfo);
                }

            }
            //更新order表状态
            storeOrder.setRefundStatus(2);
            storeOrder.setRefundReasonTime(DateUtil.nowDateTime());
            storeOrder.setRefundPrice(storeOrder.getPayPrice());
        }
        Boolean execute = transactionTemplate.execute(e -> {
            storeOrderInfoService.updateBatchById(orderInfos);
            updateById(storeOrder);
            storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_LOG_CANCEL, 0, "订单取消");
            return Boolean.TRUE;
        });
        if (!execute) {
            storeOrderStatusService.saveRefund(storeOrder.getId(), storeOrder.getPayPrice(), "订单更新失败");
            throw new VcaException("订单更新失败");
        } else {

            redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_ADMIN_ORDER_CANCEL_BY_USER, storeOrder.getOrderId());

            return CommonResult.success(execute);
        }
    }


    /**
     * 获取订单总数量
     *
     * @param uid 用户uid
     * @return Integer
     */
    @Override
    public Integer getOrderCountByUid(Integer uid) {
        LambdaQueryWrapper<StoreOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(StoreOrder::getPaid, true);
        lqw.eq(StoreOrder::getIsDel, false);
        lqw.eq(StoreOrder::getUid, uid);
        lqw.lt(StoreOrder::getRefundStatus, 2);
        return dao.selectCount(lqw);
    }

    /**
     * 获取用户总消费金额
     *
     * @param userId 用户uid
     * @return BigDecimal
     */
    @Override
    public BigDecimal getSumPayPriceByUid(Integer userId) {
        LambdaQueryWrapper<StoreOrder> lqw = Wrappers.lambdaQuery();
        lqw.select(StoreOrder::getPayPrice);
        lqw.eq(StoreOrder::getPaid, true);
        lqw.eq(StoreOrder::getIsDel, false);
        lqw.eq(StoreOrder::getUid, userId);
        lqw.lt(StoreOrder::getRefundStatus, 2);
        List<StoreOrder> orderList = dao.selectList(lqw);
        return orderList.stream().map(StoreOrder::getPayPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    /**
     * 获取订单数量(时间)
     *
     * @param uid 用户uid
     * @return Integer
     */
    @Override
    public Integer getOrderCountByUidAndDate(Integer uid, String date) {
        LambdaQueryWrapper<StoreOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(StoreOrder::getPaid, true);
        lqw.eq(StoreOrder::getIsDel, false);
        lqw.eq(StoreOrder::getUid, uid);
        lqw.lt(StoreOrder::getRefundStatus, 2);
        if (StrUtil.isNotBlank(date)) {
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(date);
            lqw.between(StoreOrder::getCreateTime, dateLimit.getStartTime(), dateLimit.getEndTime());
        }
        return dao.selectCount(lqw);
    }

    /**
     * 获取用户消费金额(时间)
     *
     * @param userId 用户uid
     * @return BigDecimal
     */
    @Override
    public BigDecimal getSumPayPriceByUidAndDate(Integer userId, String date) {
        LambdaQueryWrapper<StoreOrder> lqw = Wrappers.lambdaQuery();
        lqw.select(StoreOrder::getPayPrice);
        lqw.eq(StoreOrder::getPaid, true);
        lqw.eq(StoreOrder::getIsDel, false);
        lqw.eq(StoreOrder::getUid, userId);
        lqw.lt(StoreOrder::getRefundStatus, 2);
        if (StrUtil.isNotBlank(date)) {
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(date);
            lqw.between(StoreOrder::getCreateTime, dateLimit.getStartTime(), dateLimit.getEndTime());
        }
        List<StoreOrder> orderList = dao.selectList(lqw);
        return orderList.stream().map(StoreOrder::getPayPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
    }


    /**
     * 获取订单状态数量
     *
     * @return StoreOrderCountItemResponse
     */
    @Override
    public StoreOrderCountItemResponse getOrderStatusNum(String dateLimit, Integer type) {
        StoreOrderCountItemResponse response = new StoreOrderCountItemResponse();
        if (type.equals(5)) {
            type = null;
        }
        // 全部订单
        response.setAll(getCount(dateLimit, Constants.ORDER_STATUS_ALL, type));
        // 未支付订单
        response.setUnPaid(getCount(dateLimit, Constants.ORDER_STATUS_UNPAID, type));
        // 未发货订单
        response.setNotShipped(getCount(dateLimit, Constants.ORDER_STATUS_NOT_SHIPPED, type));
        // 待收货订单
        response.setSpike(getCount(dateLimit, Constants.ORDER_STATUS_SPIKE, type));
        // 待评价订单
        response.setBargain(getCount(dateLimit, Constants.ORDER_STATUS_BARGAIN, type));
        // 交易完成订单
        response.setComplete(getCount(dateLimit, Constants.ORDER_STATUS_COMPLETE, type));
        // 申请退款订单
        response.setApplyRefund(getCount(dateLimit, Constants.ORDER_STATUS_APPLY_REFUNDING, type));
        // 待退货订单
        response.setPendingReturn(getCount(dateLimit, Constants.PENDING_RETURN, type));
        // 退货中订单
        response.setInReturn(getCount(dateLimit, Constants.IN_RETURN, type));
        // 待核销订单
        response.setToBeWrittenOff(getCount(dateLimit, Constants.ORDER_STATUS_TOBE_WRITTEN_OFF, type));
        // 退款中订单
        response.setRefunding(getCount(dateLimit, Constants.ORDER_STATUS_REFUNDING, type));
        // 已退款订单
        response.setRefunded(getCount(dateLimit, Constants.ORDER_STATUS_REFUNDED, type));
        // 已删除订单
        response.setDeleted(getCount(dateLimit, Constants.ORDER_STATUS_DELETED, type));
        return response;
    }

    /**
     * 获取订单状态数量
     *
     * @return StoreOrderCountItemResponse
     */
    @Override
    public StoreOrderCountItemResponse getOrderStatusNum(String dateLimit, Integer type, String productName, String lecturerPhone, String realName, String schedulingDate, String orderNo) {
        StoreOrderCountItemResponse response = new StoreOrderCountItemResponse();
        if (type.equals(5)) {
            type = null;
        }
        // 全部订单
        response.setAll(getCount(dateLimit, Constants.ORDER_STATUS_ALL, type, productName, lecturerPhone, realName, schedulingDate, orderNo));
        // 未支付订单
        response.setUnPaid(getCount(dateLimit, Constants.ORDER_STATUS_UNPAID, type, productName, lecturerPhone, realName, schedulingDate, orderNo));
        // 未发货订单
        response.setNotShipped(getCount(dateLimit, Constants.ORDER_STATUS_NOT_SHIPPED, type, productName, lecturerPhone, realName, schedulingDate, orderNo));
        // 待收货订单
        response.setSpike(getCount(dateLimit, Constants.ORDER_STATUS_SPIKE, type, productName, lecturerPhone, realName, schedulingDate, orderNo));
        // 待评价订单
        response.setBargain(getCount(dateLimit, Constants.ORDER_STATUS_BARGAIN, type, productName, lecturerPhone, realName, schedulingDate, orderNo));
        // 交易完成订单
        response.setComplete(getCount(dateLimit, Constants.ORDER_STATUS_COMPLETE, type, productName, lecturerPhone, realName, schedulingDate, orderNo));
        // 申请退款订单
        response.setApplyRefund(getCount(dateLimit, Constants.ORDER_STATUS_APPLY_REFUNDING, type, productName, lecturerPhone, realName, schedulingDate, orderNo));
        // 待退货订单
        response.setPendingReturn(getCount(dateLimit, Constants.PENDING_RETURN, type, productName, lecturerPhone, realName, schedulingDate, orderNo));
        // 退货中订单
        response.setInReturn(getCount(dateLimit, Constants.IN_RETURN, type, productName, lecturerPhone, realName, schedulingDate, orderNo));
        // 待核销订单
        response.setToBeWrittenOff(getCount(dateLimit, Constants.ORDER_STATUS_TOBE_WRITTEN_OFF, type, productName, lecturerPhone, realName, schedulingDate, orderNo));
        // 退款中订单
        response.setRefunding(getCount(dateLimit, Constants.ORDER_STATUS_REFUNDING, type, productName, lecturerPhone, realName, schedulingDate, orderNo));
        // 已退款订单
        response.setRefunded(getCount(dateLimit, Constants.ORDER_STATUS_REFUNDED, type, productName, lecturerPhone, realName, schedulingDate, orderNo));
        // 已删除订单
        response.setDeleted(getCount(dateLimit, Constants.ORDER_STATUS_DELETED, type, productName, lecturerPhone, realName, schedulingDate, orderNo));
        return response;
    }

    /**
     * 获取订单统计数据
     *
     * @param dateLimit 时间端
     * @return StoreOrderTopItemResponse
     */
    @Override
    public StoreOrderTopItemResponse getOrderData(String dateLimit) {
        StoreOrderTopItemResponse itemResponse = new StoreOrderTopItemResponse();
        // 订单数量
        itemResponse.setCount(getCount(dateLimit, Constants.ORDER_STATUS_ALL));
        // 订单金额
        itemResponse.setAmount(getAmount(dateLimit, ""));
        // 微信支付金额
        itemResponse.setWeChatAmount(getAmount(dateLimit, Constants.PAY_TYPE_WE_CHAT));
        // 余额支付金额
        itemResponse.setYueAmount(getAmount(dateLimit, Constants.PAY_TYPE_YUE));
        return itemResponse;
    }

    /**
     * 订单删除
     *
     * @param orderNo 订单编号
     * @return Boolean
     */
    @Override
    public Boolean delete(String orderNo) {
        StoreOrder storeOrder = getInfoException(orderNo);
        if (!storeOrder.getIsDel()) {
            throw new VcaException("您选择的的订单存在用户未删除的订单，无法删除用户未删除的订单！");
        }
        if (storeOrder.getIsSystemDel()) {
            throw new VcaException("此订单已经被删除了!");
        }
        storeOrder.setIsSystemDel(true);
        return updateById(storeOrder);
    }

    /**
     * 通过日期获取商品交易件数
     *
     * @param date 日期，yyyy-MM-dd格式
     * @return Integer
     */
    @Override
    public Integer getOrderProductNumByDate(String date) {
        QueryWrapper<StoreOrder> wrapper = new QueryWrapper<>();
        wrapper.select("IFNULL(sum(total_num), 0) as total_num");
        wrapper.apply("date_format(create_time, '%Y-%m-%d') = {0}", date);
        StoreOrder storeOrder = dao.selectOne(wrapper);
        return storeOrder.getTotalNum();
    }

    /**
     * 通过日期获取商品交易成功件数
     *
     * @param date 日期，yyyy-MM-dd格式
     * @return Integer
     */
    @Override
    public Integer getOrderSuccessProductNumByDate(String date) {
        QueryWrapper<StoreOrder> wrapper = new QueryWrapper<>();
        wrapper.select("IFNULL(sum(total_num), 0) as total_num");
        wrapper.eq("paid", 1);
        wrapper.apply("date_format(create_time, '%Y-%m-%d') = {0}", date);
        StoreOrder storeOrder = dao.selectOne(wrapper);
        return storeOrder.getTotalNum();
    }

    /**
     * 通过日期获取订单数量
     *
     * @param date 日期，yyyy-MM-dd格式
     * @return Integer
     */
    @Override
    public Integer getOrderNumByDate(String date) {
        QueryWrapper<StoreOrder> wrapper = new QueryWrapper<>();
        wrapper.select("id");
        wrapper.eq("paid", 1);
        wrapper.apply("date_format(create_time, '%Y-%m-%d') = {0}", date);
        return dao.selectCount(wrapper);
    }

    /**
     * 通过日期获取支付订单数量
     *
     * @param date 日期，yyyy-MM-dd格式
     * @return Integer
     */
    @Override
    public Integer getPayOrderNumByDate(String date) {
        QueryWrapper<StoreOrder> wrapper = new QueryWrapper<>();
        wrapper.select("id");
        wrapper.eq("paid", 1);
        wrapper.apply("date_format(create_time, '%Y-%m-%d') = {0}", date);
        return dao.selectCount(wrapper);
    }

    /**
     * 通过日期获取支付订单金额
     *
     * @param date 日期，yyyy-MM-dd格式
     * @return BigDecimal
     */
    @Override
    public BigDecimal getPayOrderAmountByDate(String date) {
        QueryWrapper<StoreOrder> wrapper = new QueryWrapper<>();
        wrapper.select("IFNULL(sum(pay_price), 0) as pay_price");
        wrapper.eq("paid", 1);
        wrapper.apply("date_format(create_time, '%Y-%m-%d') = {0}", date);
        StoreOrder storeOrder = dao.selectOne(wrapper);
        return storeOrder.getPayPrice();
    }

    /**
     * 通过日期获取支付订单金额
     *
     * @param startDate 日期
     * @param endDate   日期
     * @return BigDecimal
     */
    @Override
    public BigDecimal getPayOrderAmountByPeriod(String startDate, String endDate) {
        QueryWrapper<StoreOrder> wrapper = new QueryWrapper<>();
        wrapper.select("IFNULL(sum(pay_price), 0) as pay_price");
        wrapper.eq("paid", 1);
        wrapper.apply("date_format(create_time, '%Y-%m-%d') between {0} and {1}", startDate, endDate);
        StoreOrder storeOrder = dao.selectOne(wrapper);
        return storeOrder.getPayPrice();
    }

    /**
     * 通过日期获取余额支付订单支付金额
     *
     * @param date 日期，yyyy-MM-dd格式
     * @return BigDecimal
     */
    @Override
    public BigDecimal getYuePayOrderAmountByDate(String date) {
        QueryWrapper<StoreOrder> wrapper = new QueryWrapper<>();
        wrapper.select("IFNULL(sum(pay_price), 0) as pay_price");
        wrapper.eq("paid", 1);
        wrapper.eq("pay_type", "yue");
        wrapper.apply("date_format(create_time, '%Y-%m-%d') = {0}", date);
        StoreOrder storeOrder = dao.selectOne(wrapper);
        return storeOrder.getPayPrice();
    }

    /**
     * 获取累计消费金额
     *
     * @return BigDecimal
     */
    @Override
    public BigDecimal getTotalPrice() {
        QueryWrapper<StoreOrder> wrapper = new QueryWrapper<>();
        wrapper.select("IFNULL(sum(pay_price), 0) as pay_price");
        wrapper.eq("paid", 1);
        StoreOrder storeOrder = dao.selectOne(wrapper);
        return storeOrder.getPayPrice();
    }

    /**
     * 根据日期获取下单用户数量
     *
     * @param date 日期
     * @return Integer
     */
    @Override
    public Integer getOrderUserNumByDate(String date) {
        QueryWrapper<StoreOrder> wrapper = new QueryWrapper<>();
        wrapper.select("id");
        wrapper.apply("date_format(create_time, '%Y-%m-%d') = {0}", date);
        wrapper.groupBy("uid");
        List<StoreOrder> orderList = dao.selectList(wrapper);
        if (CollUtil.isEmpty(orderList)) {
            return 0;
        }
        return orderList.size();
    }

    /**
     * 根据日期获取下单用户数量
     *
     * @param startDate 日期
     * @param endDate   日期
     * @return Integer
     */
    @Override
    public Integer getOrderUserNumByPeriod(String startDate, String endDate) {
        QueryWrapper<StoreOrder> wrapper = new QueryWrapper<>();
        wrapper.select("id");
        wrapper.apply("date_format(create_time, '%Y-%m-%d') between {0} and {1}", startDate, endDate);
        wrapper.groupBy("uid");
        List<StoreOrder> orderList = dao.selectList(wrapper);
        if (CollUtil.isEmpty(orderList)) {
            return 0;
        }
        return orderList.size();
    }

    /**
     * 根据日期获取成交用户数量
     *
     * @param date 日期
     * @return Integer
     */
    @Override
    public Integer getOrderPayUserNumByDate(String date) {
        QueryWrapper<StoreOrder> wrapper = new QueryWrapper<>();
        wrapper.select("id");
        wrapper.eq("paid", 1);
        wrapper.apply("date_format(create_time, '%Y-%m-%d') = {0}", date);
        wrapper.groupBy("uid");
        List<StoreOrder> orderList = dao.selectList(wrapper);
        if (CollUtil.isEmpty(orderList)) {
            return 0;
        }
        return orderList.size();
    }

    /**
     * 根据日期获取成交用户数量
     *
     * @param startDate 日期
     * @param endDate   日期
     * @return Integer
     */
    @Override
    public Integer getOrderPayUserNumByPeriod(String startDate, String endDate) {
        QueryWrapper<StoreOrder> wrapper = new QueryWrapper<>();
        wrapper.select("id");
        wrapper.eq("paid", 1);
        wrapper.apply("date_format(create_time, '%Y-%m-%d') between {0} and {1}", startDate, endDate);
        wrapper.groupBy("uid");
        List<StoreOrder> orderList = dao.selectList(wrapper);
        if (CollUtil.isEmpty(orderList)) {
            return 0;
        }
        return orderList.size();
    }

    /**
     * 根据用户uid列表获取成交用户数量
     *
     * @param uidList 用户列表
     * @return Integer
     */
    @Override
    public Integer getOrderPayUserNumByUidList(List<Integer> uidList) {
        QueryWrapper<StoreOrder> wrapper = new QueryWrapper<>();
        wrapper.select("id");
        wrapper.eq("paid", 1);
        wrapper.in("uid", uidList);
        wrapper.groupBy("uid");
        List<StoreOrder> orderList = dao.selectList(wrapper);
        if (CollUtil.isEmpty(orderList)) {
            return 0;
        }
        return orderList.size();
    }

    /**
     * 根据用户uid列表获取支付金额
     *
     * @param uidList 用户列表
     * @return BigDecimal
     */
    @Override
    public BigDecimal getPayOrderAmountByUidList(List<Integer> uidList) {
        QueryWrapper<StoreOrder> wrapper = new QueryWrapper<>();
        wrapper.select("IFNULL(sum(pay_price), 0.00) as pay_price");
//        wrapper.select("ifnull(if(sum(pay_price) = 0.00, 0, sum(pay_price)), 0) as pay_price");
        wrapper.eq("paid", 1);
        wrapper.in("uid", uidList);
        List<StoreOrder> orderList = dao.selectList(wrapper);
        if (CollUtil.isEmpty(orderList)) {
            return BigDecimal.ZERO;
        }
        return orderList.stream().map(StoreOrder::getPayPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    /**
     * 获取待发货订单数量
     *
     * @return Integer
     */
    @Override
    public Integer getNotShippingNum() {
        return getCount("", Constants.ORDER_STATUS_NOT_SHIPPED);
    }

    /**
     * 获取退款中订单数量
     */
    @Override
    public Integer getRefundingNum() {
        return getCount("", Constants.ORDER_STATUS_REFUNDING);
    }

    /**
     * 获取待核销订单数量
     */
    @Override
    public Integer getNotWriteOffNum() {
        return getCount("", Constants.ORDER_STATUS_TOBE_WRITTEN_OFF);
    }

    /**
     * 获取佣金相关数据
     *
     * @param uid      用户uid
     * @param spreadId 推广人uid
     */
    @Override
    public OrderBrokerageData getBrokerageData(Integer uid, Integer spreadId) {
        return dao.getBrokerageData(uid, spreadId);
    }

    @Override
    public List<StoreOrder> getOrderByMerOrderIdAndTargetOrderId(String merOrderId, String targetOrderId) {
        LambdaQueryWrapper<StoreOrder> wrapper = new LambdaQueryWrapper();
        if (ObjectUtil.isNotEmpty(merOrderId)) {
            wrapper.eq(StoreOrder::getUmsMerOrderId, merOrderId);
        } else if (ObjectUtil.isNotEmpty(targetOrderId)) {
            wrapper.eq(StoreOrder::getTargetOrderId, targetOrderId);
        } else {
            return null;
        }
        return dao.selectList(wrapper);
    }

    /**
     * 根据 多订单id查询
     *
     * @param orderIds
     * @return
     */
    @Override
    public List<StoreOrder> getOrderByOrderIds(List<String> orderIds) {
        LambdaQueryWrapper<StoreOrder> wrapper = new LambdaQueryWrapper();
        wrapper.in(StoreOrder::getOrderId, orderIds);
        return dao.selectList(wrapper);
    }

    /**
     * @param talkId
     * @param uid
     * @return java.util.List<com.vca.common.model.order.StoreOrder>
     * @description 跟据讲座id和用户id查询讲座订单
     * @methodName getTalkOrderByScheduleId
     * @author Li
     * @date 2022/12/29 10:35
     */
    @Override
    public List<StoreOrder> getTalkOrderByScheduleId(Long talkId, Integer uid) {
        return dao.getTalkOrderByScheduleId(talkId, uid);
    }

    /**
     * 取消活动
     *
     * @param schedulingId 排期id
     * @param type         0 课程 2 讲座 3 展览
     * @return
     */

    @Override
    public Boolean cancelActivity(Integer schedulingId, Integer type) {
        if (ObjectUtil.isNull(schedulingId) || ObjectUtil.isNull(type)) {
            throw new VcaException("排期id不能为空");
        }

        List<StoreOrderInfo> storeOrderInfos = new ArrayList<>();
        //订单详情集合
        if (type.equals(0)) {
            storeOrderInfos = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getSchedulingId, schedulingId).in(StoreOrderInfo::getType, 0, 1).eq(StoreOrderInfo::getStatus, 1).eq(StoreOrderInfo::getRefundStatus, 0));
        } else {
            storeOrderInfos = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getSchedulingId, schedulingId).eq(StoreOrderInfo::getType, type).eq(StoreOrderInfo::getStatus, 1).eq(StoreOrderInfo::getRefundStatus, 0));
        }

        if (CollUtil.isEmpty(storeOrderInfos)) {
            return true;
        }

        //订单号集合
        List<String> orderNos = storeOrderInfos.stream().map(StoreOrderInfo::getOrderNo).distinct().collect(Collectors.toList());
        //订单集合
        List<StoreOrder> storeOrders = getOrderByOrderIds(orderNos);

        //未支付订单集合
        ArrayList<StoreOrder> noPriceOrderArrayList = new ArrayList<>();
        //无需退款订单集合
        ArrayList<StoreOrder> storeOrderArrayList = new ArrayList<>();
        //无需退款订单详情集合
        ArrayList<StoreOrderInfo> storeOrderInfoArrayList = new ArrayList<>();

        //需要发消息通知 回滚库存的子订单号
        String myMerOrderNo = "";
        storeOrders.forEach(e -> {
            //如果订单已取消则不做改变

            if (!e.getIsDel() || !e.getIsSystemDel()) {
                //未支付订单自动取消并发送订阅消息
                if (!e.getPaid()) {
                    e.setIsDel(true);
                    e.setIsSystemDel(true);
                    noPriceOrderArrayList.add(e);
                    //如果该订单为后台赠送或实际支付金额为0 则不需要走退款 直接变更状态
                } else if (e.getUserType().equals(1) || e.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
                    //order
                    e.setRefundStatus(2);
                    e.setRefundPrice(BigDecimal.ZERO);
                    storeOrderArrayList.add(e);
                    //orderInfo
                    for (StoreOrderInfo storeOrderInfo : storeOrderInfoService.getListByOrderNo(e.getOrderId())) {
                        if (storeOrderInfo.getStatus().equals(1) && storeOrderInfo.getRefundStatus().equals(0)) {
                            storeOrderInfo.setRefundStatus(2);
                            storeOrderInfoArrayList.add(storeOrderInfo);
                        }
                    }
                } else { //退款
                    List<StoreOrderInfo> storeOrderInfoList = storeOrderInfoService.getListByOrderNo(e.getOrderId());
                    List<UmsPayRefundVo> refundList = new ArrayList();
                    for (StoreOrderInfo storeOrderInfo : storeOrderInfoList) {
                        if (storeOrderInfo.getStatus().equals(1) && storeOrderInfo.getRefundStatus().equals(0)) {
                            UmsPayRefundVo vo = new UmsPayRefundVo();
                            vo.setMerOrderNo(storeOrderInfo.getMerOrderNo());
                            vo.setAmount(storeOrderInfo.getPayPrice());
                            refundList.add(vo);
                        }
                    }
                    //退款
                    Boolean refund = umsPayService.refund(refundList);

                    if (refund) {
                        //回滚库存  消息通知
                        redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_ACTIVITY_CANCEL_BY_USER, e.getOrderId() + "," + schedulingId);
                    }
                }
            }
        });
        //订单为后台赠送或实际支付金额为0 则不需要走退款 直接变更状态
        Boolean execute = transactionTemplate.execute(ex -> {
            if (CollUtil.isNotEmpty(storeOrderArrayList) && CollUtil.isNotEmpty(storeOrderInfoArrayList)) {
                updateBatchById(storeOrderArrayList);
                storeOrderInfoService.updateBatchById(storeOrderInfoArrayList);
            }
            if (CollUtil.isNotEmpty(noPriceOrderArrayList)) {
                updateBatchById(noPriceOrderArrayList);
            }
            return Boolean.TRUE;
        });
        if (execute) {
            for (StoreOrder storeOrder : noPriceOrderArrayList) {//未付款
                storeOrderStatusService.createLog(storeOrder.getId(), "cancelActivity", 0, "活动取消");
                redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_ACTIVITY_CANCEL_BY_USER, storeOrder.getOrderId() + "," + schedulingId);
            }
            for (StoreOrder storeOrder : storeOrderArrayList) {//无需退款
                storeOrderStatusService.createLog(storeOrder.getId(), "cancelActivity", 0, "活动取消");
                redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_ACTIVITY_CANCEL_BY_USER, storeOrder.getOrderId() + "," + schedulingId);
            }
        } else {
            throw new VcaException("活动取消失败");
        }
        return execute;
    }


///////////////////////////////////////////////////////////////////////////////////////////////////// 以下为自定义方法

    /**
     * 根据时间参数获取有效订单
     *
     * @return 有效订单列表
     */
    private List<StoreOrder> getOrderPayedByDateLimit(String startTime, String endTime) {
        LambdaQueryWrapper<StoreOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(StoreOrder::getIsDel, false).eq(StoreOrder::getPaid, true).eq(StoreOrder::getRefundStatus, 0)
                .between(StoreOrder::getCreateTime, startTime, endTime);
        return dao.selectList(lqw);
    }

    private StoreOrder getInfoException(String orderNo) {
        LambdaQueryWrapper<StoreOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(StoreOrder::getOrderId, orderNo);
        StoreOrder storeOrder = dao.selectOne(lqw);
        if (ObjectUtil.isNull(storeOrder)) {
            throw new VcaException("没有找到订单信息");
        }
        return storeOrder;
    }


    /**
     * 获取订单总数
     *
     * @param dateLimit 时间端
     * @param status    String 状态
     * @return Integer
     */
    private Integer getCount(String dateLimit, String status) {
        //总数只计算时间
        QueryWrapper<StoreOrder> queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(dateLimit)) {
            dateLimitUtilVo dateLimitUtilVo = DateUtil.getDateLimit(dateLimit);
            queryWrapper.between("create_time", dateLimitUtilVo.getStartTime(), dateLimitUtilVo.getEndTime());
        }
//        if (status.equals(Constants.ORDER_STATUS_REFUNDING)) {
//            List<StoreOrderInfo> storeOrderInfos = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().in(StoreOrderInfo::getRefundStatus, 1));
//            List<String> orderNos = storeOrderInfos.stream().map(StoreOrderInfo::getOrderNo).distinct().collect(Collectors.toList());
//            if (CollUtil.isNotEmpty(orderNos)) {
//                queryWrapper.in("order_id", orderNos);
//            }
//        } else if (status.equals(Constants.ORDER_STATUS_REFUNDED)) {
//            List<StoreOrderInfo> storeOrderInfos = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().in(StoreOrderInfo::getRefundStatus, 2));
//            List<String> orderNos = storeOrderInfos.stream().map(StoreOrderInfo::getOrderNo).distinct().collect(Collectors.toList());
//            if (CollUtil.isNotEmpty(orderNos)) {
//                queryWrapper.in("order_id", orderNos);
//            }
//        } else {
//            getStatusWhereNew(queryWrapper, status);
//        }
        getStatusWhereNew(queryWrapper, status);
        return dao.selectCount(queryWrapper);
    }

    /**
     * 获取订单总数
     *
     * @param dateLimit 时间端
     * @param status    String 状态
     * @return Integer
     */
    private Integer getCount(String dateLimit, String status, Integer type) {
        //总数只计算时间
        QueryWrapper<StoreOrder> queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(dateLimit)) {
            dateLimitUtilVo dateLimitUtilVo = DateUtil.getDateLimit(dateLimit);
            queryWrapper.between("create_time", dateLimitUtilVo.getStartTime(), dateLimitUtilVo.getEndTime());
        }
//        if (status.equals(Constants.ORDER_STATUS_REFUNDING)) {
//            List<StoreOrderInfo> storeOrderInfos = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().in(StoreOrderInfo::getRefundStatus, 1));
//            List<String> orderNos = storeOrderInfos.stream().map(StoreOrderInfo::getOrderNo).distinct().collect(Collectors.toList());
//            if (CollUtil.isNotEmpty(orderNos)) {
//                queryWrapper.in("order_id", orderNos);
//            } else {
//                getStatusWhereNew(queryWrapper, status);
//            }
//        } else if (status.equals(Constants.ORDER_STATUS_REFUNDED)) {
//            List<StoreOrderInfo> storeOrderInfos = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().in(StoreOrderInfo::getRefundStatus, 2));
//            List<String> orderNos = storeOrderInfos.stream().map(StoreOrderInfo::getOrderNo).distinct().collect(Collectors.toList());
//            if (CollUtil.isNotEmpty(orderNos)) {
//                queryWrapper.in("order_id", orderNos);
//            } else {
//                getStatusWhereNew(queryWrapper, status);
//            }
//        } else {
//            getStatusWhereNew(queryWrapper, status);
//        }
        getStatusWhereNew(queryWrapper, status);
        if (ObjectUtil.isNotNull(type)) {
            queryWrapper.eq("type", type);
        }
        return dao.selectCount(queryWrapper);
    }

    private Integer getCount(String dateLimit, String status, Integer type, String productName, String lecturerPhone, String realName, String schedulingDate, String orderNo) {
        //总数只计算时间
        QueryWrapper<StoreOrder> queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(orderNo)) {
            queryWrapper.like("order_id", orderNo);
        }
        if (StrUtil.isNotBlank(dateLimit)) {
            dateLimitUtilVo dateLimitUtilVo = DateUtil.getDateLimit(dateLimit);
            queryWrapper.between("create_time", dateLimitUtilVo.getStartTime(), dateLimitUtilVo.getEndTime());
        }
        getStatusWhereNew(queryWrapper, status);
        if (ObjectUtil.isNotNull(type)) {
            queryWrapper.eq("type", type);
        }

        //若商品名称 和 预订单手机号不为空，则先查找详情，再找到主表id
        if (StrUtil.isNotBlank(productName) || StrUtil.isNotBlank(lecturerPhone) || StrUtil.isNotBlank(schedulingDate)) {

            QueryWrapper<StoreOrderInfo> infoQueryWrapper = new QueryWrapper<>();
            infoQueryWrapper.like(StrUtil.isNotBlank(productName), "name", productName);
            if (StrUtil.isNotBlank(lecturerPhone)) {
                infoQueryWrapper.and(wrapper -> wrapper.like("lecturer_phone", lecturerPhone).or().like("lecturer_name", lecturerPhone));
            }
            if (StringUtils.isNotBlank(schedulingDate)) {
                String[] split = schedulingDate.split(",");
                String sDate = split[0];
                String eDate = split[1];
                infoQueryWrapper.between("scheduling_date", sDate, eDate);
            }
            List<StoreOrderInfo> infoList = StoreOrderInfoService.list(infoQueryWrapper);
            if (CollectionUtil.isNotEmpty(infoList)) {
                queryWrapper.in("order_id", infoList.stream().map(StoreOrderInfo::getOrderNo).collect(Collectors.toList()));
            } else {
                //说明不存在，返回空
                return 0;
            }
        }
        //用户，手机，邮箱模糊查询
        if (StrUtil.isNotBlank(realName)) {
            QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.like("nickname", realName).or().like("phone", realName).or().like("email", realName);
            List<User> userList = userService.list(userQueryWrapper);
            if (CollectionUtil.isNotEmpty(userList)) {
                queryWrapper.in("uid", userList.stream().map(User::getUid).collect(Collectors.toList()));
            } else {
                //说明不存在，返回空
                return 0;
            }
        }

        return dao.selectCount(queryWrapper);
    }

    /**
     * 获取订单金额
     *
     * @param dateLimit 时间端
     * @param type      支付类型
     * @return Integer
     */
    private BigDecimal getAmount(String dateLimit, String type) {
        QueryWrapper<StoreOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(pay_price) as pay_price");
        if (StringUtils.isNotBlank(type)) {
            queryWrapper.eq("pay_type", type);
        }
        queryWrapper.isNotNull("pay_time");
        queryWrapper.eq("paid", 1);
        if (StringUtils.isNotBlank(dateLimit)) {
            dateLimitUtilVo dateLimitUtilVo = DateUtil.getDateLimit(dateLimit);
            queryWrapper.between("create_time", dateLimitUtilVo.getStartTime(), dateLimitUtilVo.getEndTime());
        }
        StoreOrder storeOrder = dao.selectOne(queryWrapper);
        if (ObjectUtil.isNull(storeOrder)) {
            return BigDecimal.ZERO;
        }
        return storeOrder.getPayPrice();
    }

    /**
     * 获取request的where条件
     *
     * @param queryWrapper QueryWrapper<StoreOrder> 表达式
     * @param request      StoreOrderSearchRequest 请求参数
     */
    private void getRequestTimeWhere(QueryWrapper<StoreOrder> queryWrapper, StoreOrderSearchRequest request) {
        if (StringUtils.isNotBlank(request.getDateLimit())) {
            dateLimitUtilVo dateLimitUtilVo = DateUtil.getDateLimit(request.getDateLimit());
            queryWrapper.between("create_time", dateLimitUtilVo.getStartTime(), dateLimitUtilVo.getEndTime());
        }
    }

    /**
     * 根据订单状态获取where条件
     *
     * @param queryWrapper QueryWrapper<StoreOrder> 表达式
     * @param status       String 类型
     */
    private void getStatusWhereNew(QueryWrapper<StoreOrder> queryWrapper, String status) {
        if (StrUtil.isBlank(status)) {
            return;
        }
        switch (status) {
            case Constants.ORDER_STATUS_ALL: //全部
                break;
            case Constants.ORDER_STATUS_UNPAID: //未支付
                queryWrapper.eq("paid", 0);//支付状态
                queryWrapper.eq("status", 0); //订单状态
                queryWrapper.eq("is_del", 0);//删除状态
                break;
            case Constants.ORDER_STATUS_NOT_SHIPPED: //未发货
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("status", 0);
                queryWrapper.eq("refund_status", 0);
                queryWrapper.eq("type", 4);//订单类型为商品
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_SPIKE: //待收货
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("status", 1);
                queryWrapper.eq("type", 4);//订单类型为商品
                queryWrapper.eq("refund_status", 0);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_BARGAIN: //待评价
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("status", 2);
                queryWrapper.eq("refund_status", 0);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_COMPLETE: //交易完成
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("status", 3);
                queryWrapper.in("refund_status", 0, 6);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_APPLY_REFUNDING: //申请退款
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("refund_status", 1);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.PENDING_RETURN: //待退货
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("refund_status", 4);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.IN_RETURN: //退货中
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("refund_status", 5);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_TOBE_WRITTEN_OFF: //待核销
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("status", 1);
                queryWrapper.eq("refund_status", 0);
                queryWrapper.ne("type", 4);//订单类型为课程套课讲座展览
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_REFUNDING: //退款中
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("refund_status", 3);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_REFUNDED: //已退款
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("refund_status", 2);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_DELETED: //已删除
                queryWrapper.eq("is_del", 1);
                break;
            default:
                queryWrapper.eq("paid", 1);
                queryWrapper.ne("refund_status", 2);
                break;
        }
    }

    /**
     * 根据订单状态获取where条件
     *
     * @param queryWrapper QueryWrapper<StoreOrder> 表达式
     * @param status       String 类型
     */
    private void getStatusWhere(QueryWrapper<StoreOrder> queryWrapper, String status) {
        if (StrUtil.isBlank(status)) {
            return;
        }

        switch (status) {
            case Constants.ORDER_STATUS_UNPAID: //未支付
                queryWrapper.eq("paid", 0);//支付状态
                queryWrapper.eq("status", 0); //订单状态
                queryWrapper.eq("is_del", 0);//删除状态
                break;
            case Constants.ORDER_STATUS_NOT_SHIPPED: //未发货
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("status", 0);
                queryWrapper.eq("refund_status", 0);
                queryWrapper.notIn("type", 0, 1, 2, 3);//不等于非商品
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_SPIKE: //待收货
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("status", 1);
                queryWrapper.eq("type", 4);
                queryWrapper.eq("refund_status", 0);
                queryWrapper.eq("type", 4);//不等于非商品
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_TOBE_WRITTEN_OFF: //待核销
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("status", 1);
                queryWrapper.ne("type", 4);
                queryWrapper.eq("refund_status", 0);
//                queryWrapper.eq("shipping_type", 2);//配送方式
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_BARGAIN: //待评价
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("status", 2);
                queryWrapper.eq("refund_status", 0);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_COMPLETE: //交易完成
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("status", 3);
                queryWrapper.in("refund_status", 0, 6);
                queryWrapper.eq("is_del", 0);
                break;

            case Constants.ORDER_STATUS_APPLY_REFUNDING: //申请退款
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("refund_status", 1);
                queryWrapper.eq("is_del", 0);
                break;

            case Constants.PENDING_RETURN: //待退货
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("refund_status", 4);
                queryWrapper.eq("is_del", 0);
                break;

            case Constants.IN_RETURN: //退货中
//                storeOrderInfoService.list(new LambdaQueryWrapper<>());
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("refund_status", 5);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_REFUNDING: //退款中
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("refund_status", 3);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_REFUNDED: //已退款
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("refund_status", 2);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_DELETED: //已取消
                queryWrapper.eq("is_del", 1);
                break;
            default:
                queryWrapper.eq("paid", 1);
                queryWrapper.ne("refund_status", 2);
                break;
        }
//        if (Constants.ORDER_STATUS_DELETED.equals(status)){
//            queryWrapper.last("is_del =1 or is_system_del");
//        }
    }

    /**
     * 获取订单状态
     *
     * @param storeOrder StoreOrder 订单信息
     * @author Mr.Zhang
     * @since 2020-06-12
     */
    private Map<String, String> getStatus(StoreOrder storeOrder) {
        Map<String, String> map = new HashMap<>();
        map.put("key", "");
        map.put("value", "");
        if (null == storeOrder) {
            return map;
        }
        // 未支付
        if (!storeOrder.getPaid()
                && storeOrder.getStatus() == 0
                && storeOrder.getRefundStatus() == 0
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_UNPAID);
            map.put("value", Constants.ORDER_STATUS_STR_UNPAID);
            return map;
        }
        // 未发货
        if (storeOrder.getPaid()
                && storeOrder.getStatus() == 0
                && storeOrder.getRefundStatus() == 0
//                && storeOrder.getShippingType() == 1
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_NOT_SHIPPED);
            map.put("value", Constants.ORDER_STATUS_STR_NOT_SHIPPED);
            return map;
        }
        // 待收货
        if (storeOrder.getPaid()
                && storeOrder.getStatus() == 1
                && storeOrder.getRefundStatus() == 0
//                && storeOrder.getShippingType() == 1
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_SPIKE);
            if (!storeOrder.getType().equals(4)) {
                map.put("value", "待核销");
            } else {
                map.put("value", Constants.ORDER_STATUS_STR_SPIKE);
            }
            return map;
        }
        // 待评价
        if (storeOrder.getPaid()
                && storeOrder.getStatus() == 2
                && storeOrder.getRefundStatus() == 0
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_BARGAIN);
            map.put("value", Constants.ORDER_STATUS_STR_BARGAIN);
            return map;
        }
        // 交易完成
        if (storeOrder.getPaid()
                && storeOrder.getStatus() == 3
                && (storeOrder.getRefundStatus() == 0 || storeOrder.getRefundStatus() == 6)
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_COMPLETE);
            map.put("value", Constants.ORDER_STATUS_STR_COMPLETE);
            return map;
        }
        // 待核销
//        if (storeOrder.getPaid()
//                && storeOrder.getStatus() == 0
//                && storeOrder.getRefundStatus() == 0
////                && storeOrder.getShippingType() == 2
//                && !storeOrder.getIsDel()
//                && !storeOrder.getIsSystemDel()) {
//            map.put("key", Constants.ORDER_STATUS_TOBE_WRITTEN_OFF);
//            map.put("value", Constants.ORDER_STATUS_STR_TOBE_WRITTEN_OFF);
//            return map;
//        }

        //申请退款
        if (storeOrder.getPaid()
                && storeOrder.getRefundStatus() == 1
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_APPLY_REFUNDING);
            map.put("value", Constants.ORDER_STATUS_STR_APPLY_REFUNDING);
            return map;
        }

        //待退货
        if (storeOrder.getPaid()
                && storeOrder.getRefundStatus() == 4
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.PENDING_RETURN);
            map.put("value", Constants.ORDER_STATUS_STR_PENDING_RETURN);
            return map;
        }

        //退货中
        if (storeOrder.getPaid()
                && storeOrder.getRefundStatus() == 5
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.IN_RETURN);
            map.put("value", Constants.ORDER_STATUS_STR_IN_RETURN);
            return map;
        }

        //退款中
        if (storeOrder.getPaid()
                && storeOrder.getRefundStatus() == 3
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_REFUNDING);
            map.put("value", Constants.ORDER_STATUS_STR_REFUNDING);
            return map;
        }

        //已退款
        if (storeOrder.getPaid()
                && storeOrder.getRefundStatus() == 2
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_REFUNDED);
            map.put("value", Constants.ORDER_STATUS_STR_REFUNDED);
        }

        //已删除
        if (storeOrder.getIsDel() || storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_DELETED);
            map.put("value", Constants.ORDER_STATUS_STR_DELETED);
        }

        return map;
    }

    /**
     * 获取支付文字
     *
     * @param payType String 支付方式
     */
    private String getPayType(String payType) {
        switch (payType) {
            case Constants.PAY_TYPE_WE_CHAT:
                return Constants.PAY_TYPE_STR_WE_CHAT;
            case Constants.PAY_TYPE_BACKEND:
                return Constants.PAY_BACKEND;
            case Constants.PAY_TYPE_ALI_PAY:
                return Constants.PAY_TYPE_STR_ALI_PAY;
            default:
                return Constants.PAY_TYPE_STR_OTHER;
        }
    }


    /**
     * @return
     * @Description:回滚库存
     * @author:chenbing
     * @date 2022/12/30 15:11
     */
    @Override
    public VcaProductStockVo rollBackStock(StoreOrder storeOrder) {
        List<CourseScheduling> courseSchedulingList = new ArrayList<>();
        List<TalkScheduling> talkSchedulingList = new ArrayList<>();
        List<ExhibitionScheduling> exhibitionSchedulingList = new ArrayList<>();
        List<VcaProduct> vcaProducts = new ArrayList<>();
        List<VcaProductAttrValue> vcaProductAttrValues = new ArrayList<>();
        switch (storeOrder.getType()) {
            case 0:
            case 1:
                List<CourseScheduling> courseSchedulings = rollBackStockOfCourse(storeOrder);
                courseSchedulings.forEach(courseScheduling -> {
                    courseSchedulingList.add(courseScheduling);
                });
                break;
            case 2:
                List<TalkScheduling> talkSchedulings = rollBackStockOfTalk(storeOrder);
                talkSchedulings.forEach(talkScheduling -> {
                    talkSchedulingList.add(talkScheduling);
                });
                break;
            case 3:
                List<ExhibitionScheduling> exhibitionSchedulings = rollBackStockOfExhibition(storeOrder);
                exhibitionSchedulings.forEach(exhibitionScheduling -> {
                    exhibitionSchedulingList.add(exhibitionScheduling);
                });
                break;
            case 4:
                VcaProductStockVo vcaProductStockVo1 = rollBackStockOfProduct(storeOrder);
                vcaProductStockVo1.getVcaProducts().forEach(vcaProduct -> {
                    vcaProducts.add(vcaProduct);
                });
                vcaProductStockVo1.getVcaProductAttrValues().forEach(vcaProductAttrValue -> {
                    vcaProductAttrValues.add(vcaProductAttrValue);
                });
                break;
            default:
                break;
        }
        VcaProductStockVo vcaProductStockVo = new VcaProductStockVo();
        vcaProductStockVo.setCourseSchedulingList(courseSchedulingList);
        vcaProductStockVo.setExhibitionSchedulingList(exhibitionSchedulingList);
        vcaProductStockVo.setTalkSchedulingList(talkSchedulingList);
        vcaProductStockVo.setVcaProductAttrValues(vcaProductAttrValues);
        vcaProductStockVo.setVcaProducts(vcaProducts);
        return vcaProductStockVo;
    }


    /**
     * @param pram
     * @return {@link List}<{@link DetailClientVo}>
     * @description 导出客户详细信息
     * @author Li
     * @date 2023/2/21 10:10
     */
    @Override
    public List<DetailClientVo> detailClient(StoreDateRangeSqlPram pram) {
        List<DetailClientVo> vos = dao.detailClient(pram);
        List<DetailClientVo> copy = new ArrayList<>();
        List<String> merOrderIds = vos.stream()
                .filter(v -> ObjectUtil.isNotEmpty(v.getCardId()) && v.getPayNum() > 1)
                .map(DetailClientVo::getMerOrderId)
                .collect(Collectors.toList());
        if (ObjectUtil.isNotEmpty(merOrderIds)){
            List<UserCard> cards = userCardService.list(
                    Wrappers.<UserCard>lambdaQuery()
                            .in(UserCard::getOrderId, merOrderIds));
            Map<String, List<UserCard>> cardsMap = cards.stream().collect(Collectors.groupingBy(UserCard::getOrderId));
            vos.forEach(v->{
                if (ObjectUtil.isNotEmpty(cardsMap.get(v.getMerOrderId()))){
                    BigDecimal payPrice = v.getPayPrice().divide(BigDecimal.valueOf(v.getPayNum()), RoundingMode.UNNECESSARY);
                    List<UserCard> userCards = cardsMap.get(v.getMerOrderId());
                    userCards.forEach(u->{
                        if (!u.getId().equals(v.getCardId())) {
                            DetailClientVo vo = new DetailClientVo();
                            BeanUtils.copyProperties(v,vo);
                            BeanUtils.copyProperties(u,vo);
                            vo.setPayPrice(payPrice);
                            vo.setStatus(u.getStutus().toString());
                            vo.setCardId(u.getId());
                            vo.setCardUid(u.getUid());
                            vo.setUid(v.getUid());
                            vo.setSchedulingPrice(payPrice.toString());
                            copy.add(vo);
                        }else {
                            v.setSchedulingPrice(payPrice.toString());
                            v.setPayPrice(payPrice);
                        }
                    });
                }
            });
            vos.addAll(copy);
        }
        List<Integer> cardList = vos.stream()
                .map(DetailClientVo::getCardId)
                .filter(ObjectUtil::isNotEmpty)
                .collect(Collectors.toList());
        if (ObjectUtil.isEmpty(cardList)) {
            return vos;
        }
        //查询礼品卡兑换的课程信息
        logger.info(JSON.toJSONString(cardList));
        Map<Integer, DetailClientVo> couponMap =
                VcaUtil.listToMap(dao.detailClientOrderByInfo(cardList), "couponId", Integer.class);
        vos.forEach(v -> {
            DetailClientVo vo = couponMap.get(v.getCardId());
            if (ObjectUtil.isNotEmpty(vo)) {
                v.setCouponName(vo.getName());
                v.setPeriods(vo.getPeriods());
                if (ObjectUtil.isEmpty(v.getCardNo())){
                    v.setCardNo(vo.getCardNo());
                }
                v.setStatus(vo.getStatus());
                v.setSchedulingDate(vo.getSchedulingDate());
                v.setSchedulingPrice(vo.getSchedulingPrice());
                v.setWriteOffTime(vo.getWriteOffTime());
            }
        });
        vos.sort(Comparator.comparing(DetailClientVo::getUid).thenComparing(DetailClientVo::getOrderId));
        return vos;

    }

    @Override
    public List<StoreOrder> summaryDay(String startTime, String endTime) {
        return dao.summaryDay(startTime, endTime);
    }

    @Override
    public List<StoreOrder> productClosing(String startTime, String endTime) {
        return dao.productClosing(startTime, endTime);
    }

    @Override
    public List<StoreOrder> productPay(String startTime, String endTime) {
        return dao.productPay(startTime, endTime);
    }

    @Override
    public List<StoreOrder> cardPay(String startTime, String endTime) {
        return dao.cardPay(startTime, endTime);
    }

    @Override
    public List<DetailClientVo> testDetailClient(StoreDateRangeSqlPram pram) {
        List<DetailClientVo> vos = dao.testDetailClient(pram);



        return vos;
    }

    @Override
    public List<StoreOrderInfoResultVo> orderCoursePackageInfo(Integer id) {
        StoreOrder storeOrder = getById(id);
        if (ObjectUtil.isNull(storeOrder)) {
            throw new VcaException("未找到对应订单信息");
        }
        //订单详情
        List<StoreOrderInfo> storeOrderInfos = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, storeOrder.getOrderId()));
        List<StoreOrderInfoResultVo> storeOrderInfoResultVoList = new ArrayList<StoreOrderInfoResultVo>();
        storeOrderInfos.forEach(storeOrderInfo -> {
            StoreOrderInfoResultVo storeOrderInfoResultVo = new StoreOrderInfoResultVo();
            BeanUtils.copyProperties(storeOrderInfo, storeOrderInfoResultVo);
            storeOrderInfoResultVo.setRemark(getOrderInfoStatus(storeOrderInfo));
            storeOrderInfoResultVoList.add(storeOrderInfoResultVo);
        });


        return storeOrderInfoResultVoList;
    }

    @Override
    public CommonResult orderCoursePackageCancel(CoursePackageCancelVo request) {
        StoreOrder storeOrder = getByOrderId(request.getOrderNo());

        if (ObjectUtil.isNull(storeOrder)) {
            throw new VcaException("该订单不存在！");
        }

        if (storeOrder.getType().equals(4)) {
            throw new VcaException("该订单类型不支持取消");
        }

        if (storeOrder.getIsDel() || storeOrder.getIsSystemDel()) {
            throw new VcaException("该订单已取消");
        }

        if (!storeOrder.getRefundStatus().equals(0) || !storeOrder.getStatus().equals(1)) {
            throw new VcaException("订单状态不支持取消");
        }
        ArrayList<String> merOrderNoList = new ArrayList();
        List<CoursePackageCancelVo.OrderCancelVo> orderCancelVoList = request.getOrderCancelVoList();
        orderCancelVoList.forEach(orderCancelVo -> {
            merOrderNoList.add(orderCancelVo.getMerOrderNo());
        });

        Map<String, CoursePackageCancelVo.OrderCancelVo> orderCancelVoMap = orderCancelVoList.stream().collect(Collectors.toMap(CoursePackageCancelVo.OrderCancelVo::getMerOrderNo, a -> a,(k1,k2)->k1));



        List<StoreOrderInfo> storeOrderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().in(StoreOrderInfo::getMerOrderNo, merOrderNoList));
        for (StoreOrderInfo storeOrderInfo : storeOrderInfoList) {
            if (storeOrderInfo.getRefundStatus() == 1) {
                throw new VcaException("正在申请退款中");
            }

            if (storeOrderInfo.getRefundStatus() == 2) {
                throw new VcaException("订单已退款");
            }

            if (storeOrderInfo.getRefundStatus() == 3) {
                throw new VcaException("订单退款中");
            }
        }

        List<StoreOrderInfo> orderInfos = new ArrayList<>();
        //退款判断  如果不是后台赠送并且金额不为0 则调用退款接口并更新订单状态为退款中
        if (storeOrder.getUserType().equals(0) && storeOrder.getPayPrice().compareTo(BigDecimal.ZERO) > 0) {
            List<UmsPayRefundVo> refundList = new ArrayList();

            for (StoreOrderInfo storeOrderInfo : storeOrderInfoList) {
                if (storeOrderInfo.getStatus().equals(1) && storeOrderInfo.getRefundStatus().equals(0)) {
                    UmsPayRefundVo umsPayRefundVo = new UmsPayRefundVo();
                    umsPayRefundVo.setMerOrderNo(storeOrderInfo.getMerOrderNo());
                    umsPayRefundVo.setAmount(orderCancelVoMap.get(storeOrderInfo.getMerOrderNo()).getPrice());
                    refundList.add(umsPayRefundVo);
                }
            }
            if (umsPayService.refund(refundList)) {
                // 退款task
                storeOrderStatusService.createLog(storeOrder.getId(), "orderCancel", 0, "订单取消");
                redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_ADMIN_ORDER_CANCEL_BY_USER, storeOrder.getOrderId());
                return CommonResult.success(true);

            } else {
                return CommonResult.failed("取消失败");
            }
        } else {
            //为后台赠送或金额为0 则直接修改订单状态为已退款 并把退款后续操作放进redis
            for (StoreOrderInfo storeOrderInfo : storeOrderInfoList) { //更新info表状态
                if (storeOrderInfo.getStatus().equals(1) && storeOrderInfo.getRefundStatus().equals(0)) {
                    storeOrderInfo.setRefundStatus(2);
                    storeOrderInfo.setRefundReasonTime(DateUtil.nowDateTime());
                    orderInfos.add(storeOrderInfo);
                }

            }
            //更新order表状态
            storeOrder.setRefundStatus(2);
            storeOrder.setRefundReasonTime(DateUtil.nowDateTime());
            storeOrder.setRefundPrice(storeOrder.getPayPrice());
        }
        Boolean execute = transactionTemplate.execute(e -> {
            storeOrderInfoService.updateBatchById(orderInfos);
            updateById(storeOrder);
            storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_LOG_CANCEL, 0, "订单取消");
            return Boolean.TRUE;
        });
        if (!execute) {
            storeOrderStatusService.saveRefund(storeOrder.getId(), storeOrder.getPayPrice(), "订单更新失败");
            throw new VcaException("订单更新失败");
        } else {

            redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_ADMIN_ORDER_CANCEL_BY_USER, storeOrder.getOrderId());

            return CommonResult.success(execute);
        }
    }

    @Override
    public List<Course> getCoursesList(StoreOrderSearchRequest request) {
        LambdaQueryWrapper<StoreOrderInfo> courseLambdaQueryWrapper = new LambdaQueryWrapper<>();
        courseLambdaQueryWrapper.eq(StoreOrderInfo::getMerOrderNo,request.getOrderNo());
        StoreOrderInfo orderInfo = storeOrderInfoService.getOne(courseLambdaQueryWrapper);

        LambdaQueryWrapper<SystemGroupData> groupDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
        groupDataLambdaQueryWrapper.like(SystemGroupData::getValue,orderInfo.getPrice());

        List<SystemGroupData> groupDataList = systemGroupDataService.list(groupDataLambdaQueryWrapper);
        List<Integer> groupDataIds = new ArrayList<>();
        groupDataList.forEach(systemGroupData -> {
            groupDataIds.add(systemGroupData.getId());
        });
        LambdaQueryWrapper<Course> courseQueryWrapper = new LambdaQueryWrapper<>();
        courseQueryWrapper.in(Course::getCoursePriceId,groupDataIds);
        courseQueryWrapper.eq(Course::getStatus, Constants.COURSE_STATUS_IS_SALE);
        courseQueryWrapper.eq(Course::getIsRecycle,"0");
        courseQueryWrapper.eq(Course::getIsDeleted,"0");
        List<Course> courseList = courseService.list(courseQueryWrapper);
        List<Course> courseListResult = new ArrayList<>();
        courseList.forEach(course -> {
            LambdaQueryWrapper<CourseScheduling> schedulingQueryWrapper = new LambdaQueryWrapper<>();
            schedulingQueryWrapper.eq(CourseScheduling::getStatus,"1");
            schedulingQueryWrapper.eq(CourseScheduling::getIsCancel,"0");
            schedulingQueryWrapper.eq(CourseScheduling::getIsDel,"0");
            schedulingQueryWrapper.eq(CourseScheduling::getCourseId,course.getId());

            List<CourseScheduling> schedulingList = courseSchedulingService.list(schedulingQueryWrapper);
            if(schedulingList.size()>0){
                //添加课程
                courseListResult.add(course);
            }
        });

        return courseListResult;
    }

    /**
     * @Description:回滚商品库存
     * @author:chenbing
     * @date 2022/12/30 15:22
     */
    private VcaProductStockVo rollBackStockOfProduct(StoreOrder order) {
        List<StoreOrderInfo> orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, order.getOrderId()));
        List<VcaProduct> vcaProducts = new ArrayList<>();
        List<VcaProductAttrValue> vcaProductAttrValues = new ArrayList<>();
        orderInfoList.forEach(orderInfo -> {
            VcaProduct product = vcaProductService.getById(orderInfo.getProductId());
            product.setStock(product.getStock() + orderInfo.getPayNum());
            VcaProductAttrValue productAttrValue = vcaProductAttrValueService.getById(orderInfo.getAttrValueId());
            productAttrValue.setStock(productAttrValue.getStock() + orderInfo.getPayNum());
            if (order.getPaid()) {
                product.setSales(product.getSales() == 0 ? 0 : product.getSales() - orderInfo.getPayNum());
                productAttrValue.setSales(productAttrValue.getSales() == 0 ? 0 : productAttrValue.getSales() - orderInfo.getPayNum());
            }
            vcaProducts.add(product);
            vcaProductAttrValues.add(productAttrValue);
        });
        VcaProductStockVo vcaProductStockVo = new VcaProductStockVo();
        vcaProductStockVo.setVcaProducts(vcaProducts);
        vcaProductStockVo.setVcaProductAttrValues(vcaProductAttrValues);
        return vcaProductStockVo;
    }

    /**
     * @Description:回滚展览排期库存
     * @author:chenbing
     * @date 2022/12/30 15:21
     */
    private List<ExhibitionScheduling> rollBackStockOfExhibition(StoreOrder order) {
        List<StoreOrderInfo> orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, order.getOrderId()));
        List<ExhibitionScheduling> exhibitionSchedulings = new ArrayList<>();
        orderInfoList.forEach(orderInfo -> {
            ExhibitionScheduling exhibitionScheduling = exhibitionSchedulingService.getOne(new LambdaQueryWrapper<ExhibitionScheduling>()
                    .eq(ExhibitionScheduling::getExhibitionId, orderInfo.getMainId())
                    .eq(ExhibitionScheduling::getId, orderInfo.getSchedulingId()));
            exhibitionScheduling.setQuota(exhibitionScheduling.getQuota() + orderInfo.getPayNum());
            if (order.getPaid()) {
                exhibitionScheduling.setNumberOfAppointments(exhibitionScheduling.getNumberOfAppointments() == 0 ? 0 : exhibitionScheduling.getNumberOfAppointments() - orderInfo.getPayNum());
            }
            exhibitionSchedulings.add(exhibitionScheduling);
        });
        return exhibitionSchedulings;
    }

    /**
     * @Description:回滚讲座排期库存
     * @author:chenbing
     * @date 2022/12/30 15:18
     */
    private List<TalkScheduling> rollBackStockOfTalk(StoreOrder order) {
        List<StoreOrderInfo> orderInfoList = new ArrayList<>();
        if (order.getIsDel() || order.getIsSystemDel()) {
            orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, order.getOrderId()));
        } else {
            orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, order.getOrderId()).eq(StoreOrderInfo::getStatus, 1).eq(StoreOrderInfo::getRefundStatus, 2));
        }
        List<TalkScheduling> talkSchedulings = new ArrayList<>();
        orderInfoList.forEach(orderInfo -> {
            TalkScheduling talkScheduling = talkSchedulingService.getOne(new LambdaQueryWrapper<TalkScheduling>()
                    .eq(TalkScheduling::getTalkId, orderInfo.getMainId())
                    .eq(TalkScheduling::getId, orderInfo.getSchedulingId()));
            talkScheduling.setQuota(talkScheduling.getQuota() + orderInfo.getPayNum());
            if (order.getPaid()) {
                talkScheduling.setNumberOfAppointments(talkScheduling.getNumberOfAppointments() == 0 ? 0 : talkScheduling.getNumberOfAppointments() - orderInfo.getPayNum());
            }
            talkSchedulings.add(talkScheduling);
        });
        return talkSchedulings;
    }

    /**
     * @Description:回滚课程排期库存
     * @author:chenbing
     * @date 2022/12/30 15:15
     */
    private List<CourseScheduling> rollBackStockOfCourse(StoreOrder order) {
        List<StoreOrderInfo> orderInfoList = new ArrayList<>();
        if (order.getIsDel() || order.getIsSystemDel()) {
            orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, order.getOrderId()));
        } else {
            orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, order.getOrderId()).eq(StoreOrderInfo::getStatus, 1).eq(StoreOrderInfo::getRefundStatus, 2));
        }

        List<CourseScheduling> courseSchedulings = new ArrayList<>();
        orderInfoList.forEach(orderInfo -> {
            LambdaQueryWrapper<CourseScheduling> lqw = new LambdaQueryWrapper<CourseScheduling>()
                    .eq(CourseScheduling::getId, orderInfo.getSchedulingId());
            if (Objects.equals(orderInfo.getType(), Constants.ORDER_TYPE_PACKAGE)) {
                lqw.eq(CourseScheduling::getCourseId, orderInfo.getTaokeAboutCourseId());
            } else {
                lqw.eq(CourseScheduling::getCourseId, orderInfo.getMainId());
            }
            CourseScheduling scheduling = courseSchedulingService.getOne(lqw);
            if (order.getUserType().equals(0)) {
                scheduling.setExternalLimit(scheduling.getExternalLimit() + orderInfo.getPayNum());
                scheduling.setExternalAppointment(scheduling.getExternalAppointment() == 0 ? 0 : scheduling.getExternalAppointment() - orderInfo.getPayNum());
                courseSchedulings.add(scheduling);
            } else {
                scheduling.setInternalLimit(scheduling.getInternalLimit() + orderInfo.getPayNum());
                scheduling.setInternalAppointment(scheduling.getInternalAppointment() == 0 ? 0 : scheduling.getInternalAppointment() - orderInfo.getPayNum());
                courseSchedulings.add(scheduling);
            }

        });
        return courseSchedulings;
    }

    private String getSystemConfigName(String name) {
        LambdaQueryWrapper<SystemConfig> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SystemConfig::getStatus, false).eq(SystemConfig::getName, name);
        SystemConfig systemConfig = systemConfigService.getOne(lambdaQueryWrapper);
        return systemConfig.getValue();
    }


}

